def switch_features_handler(self, event): """ switch sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) ########################################################################################### """ Set HF[1]=PKT_LEN [byte]""" req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) """ Update function: avg( [count] , [value_to_be_averaged] , [avg_value]) = (IO1 , IN1 , IO2) has 3 inputs and 2 outputs OUT1 = FDV[0] = count OUT2 = FDV[1] = avg(IN1)*1000 """ match = ofparser.OFPMatch() actions = [ ofparser.OFPActionOutput(ofproto.OFPP_FLOOD), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_AVG, output_fd_id=0, operand_1_hf_id=1, operand_2_fd_id=1) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """ $ sudo watch --color -n1 dpctl tcp:127.0.0.1:6634 stats-state -c
def switch_features_handler(self, event): """ switch sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC, ofproto.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC, ofproto.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(req) ########################################################################################### """ State transition """ match = ofparser.OFPMatch(in_port=3) actions = [ bebaparser.OFPExpActionSetState(table_id=0, state=1), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """ State transition for the reverse flow """ match = ofparser.OFPMatch(in_port=4) actions = [ bebaparser.OFPExpActionSetState( table_id=0, state=2, fields=[ofproto.OXM_OF_ETH_DST, ofproto.OXM_OF_ETH_SRC]), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """
def switch_features_handler(self, event): """ switch sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable( datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC,ofproto.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC,ofproto.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(req) ########################################################################################### """ Update function: FDV[0] = FDV[0]+1 (i.e. counter = counter+1) """ match = ofparser.OFPMatch(in_port=1) actions = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_fd_id=0, operand_2_cost=1), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """ Update function for the reverse flow: FDV[0] = FDV[0]+1 (i.e. counter = counter+1) """ match = ofparser.OFPMatch(in_port=2) actions = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_fd_id=0, operand_2_cost=1, fields=[ofproto.OXM_OF_ETH_DST,ofproto.OXM_OF_ETH_SRC]), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """
def switch_features_handler(self, event): """ Switche sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath devices.append(datapath) LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofp.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofp.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) # for each input port, for each state for i in range(1, N + 1): for s in range(N + 1): match = ofparser.OFPMatch(in_port=i, state=s) if s == 0: out_port = ofp.OFPP_FLOOD else: out_port = s actions = [ bebaparser.OFPExpActionSetState(state=i, table_id=0, hard_timeout=10), ofparser.OFPActionOutput(out_port) #,ofparser.OFPActionOutput(ofp.OFPP_CONTROLLER, #ofp.OFPCML_NO_BUFFER) ] # Triggers flow mod self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions)
def test8(self, datapath): self.send_table_mod(datapath) key_update_extractor = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(key_update_extractor) key_lookup_extractor = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC, ofproto.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(key_lookup_extractor)
def send_key_update(self, datapath): key_update_extractor = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC, ofproto.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(key_update_extractor)
def switch_features_handler(self, event): """ Switche sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_DST], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) # for each input port, for each state for i in range(1, N + 1): for s in range(N + 1): match = ofparser.OFPMatch(in_port=i, state=s) if s == 0: out_port = ofproto.OFPP_FLOOD else: out_port = s actions = [ bebaparser.OFPExpActionSetState(state=i, table_id=0, hard_timeout=10), ofparser.OFPActionOutput(out_port) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """ Need to drop some packets for DEMO puporses only (avoid learning before manual send_eth)"""
def switch_features_handler(self, event): msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {ip_src} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC], table_id=0) datapath.send_msg(req) """ Set update extractor = {ip_src} (same as lookup) """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC], table_id=0) datapath.send_msg(req) """ Table 0 """ """ ARP packets flooding """ match = ofparser.OFPMatch(eth_type=0x0806) actions = [ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] self.add_flow(datapath=datapath, table_id=0, priority=10, match=match, actions=actions) """ Drop IP-dst Broadcast """ match = ofparser.OFPMatch(eth_type=0x0800, ipv4_dst="255.255.255.255") actions = [] self.add_flow(datapath=datapath, table_id=0, priority=10, match=match, actions=actions) match = ofparser.OFPMatch(eth_type=0x0800) actions = [bebaparser.OFPExpActionIncState(table_id=0)] inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=inst) datapath.send_msg(mod)
def test6(self, datapath): self.send_table_mod(datapath) key_lookup_extractor = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(key_lookup_extractor) key_update_extractor = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(key_update_extractor) state = bebaparser.OFPExpMsgDelFlowState(datapath=datapath, keys=[10, 0, 0, 5], table_id=0) datapath.send_msg(state)
def test3(self, datapath): self.send_table_mod(datapath) # I provide zero fields => I cannot set an empty extractor! key_lookup_extractor = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[], table_id=0) datapath.send_msg(key_lookup_extractor) # I provide more fields than allowed key_lookup_extractor = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ ofproto.OXM_OF_ETH_SRC, ofproto.OXM_OF_ETH_DST, ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST, ofproto.OXM_OF_UDP_SRC, ofproto.OXM_OF_UDP_DST ], table_id=0) datapath.send_msg(key_lookup_extractor)
def install_stateful(self, datapath): # configure stateful stage req = bebaparser.OFPExpMsgConfigureStatefulTable( datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {ip_dst} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_DST], table_id=0) datapath.send_msg(req) """ Set update extractor = {ip_dst} (same as lookup) """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_DST], table_id=0) datapath.send_msg(req) # sampling time req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=1, value=SAMPLING_TIME) datapath.send_msg(req) # Threshold req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=MAX_PPS) datapath.send_msg(req) # threshold exceeding condition req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=1, table_id=0, operand_1_fd_id=3, operand_2_gd_id=0) datapath.send_msg(req) # time condition req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=0, table_id=0, operand_1_hf_id=1, operand_2_fd_id=1) datapath.send_msg(req) # threshold exceeding condition req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=2, table_id=0, operand_1_fd_id=2, operand_2_gd_id=0) datapath.send_msg(req) # timestamp extractor req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) # metadata extractor req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=0, field=ofproto.OXM_OF_METADATA) datapath.send_msg(req) # timestamp extractor req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=2, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) ############################### TAB 0: STATEFUL ############################################ """ For each state entry FDV[0]: count FDV[1]: delta timestamp FDV[2]: ewma representing switch's own state FDV[3]: global state """ match = ofparser.OFPMatch(eth_type=0x800, in_port=HOST_PORT) self.add_flow(datapath=datapath, priority=200, table_id=0, match=match, actions=[]) # common instructions instGoto1 = [ofparser.OFPInstructionGotoTable(1)] # packet counter ++ actionUpdateCounter = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_fd_id=0, operand_2_cost=1)] # reset counter to 0 actionResetCounter = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=0, operand_1_fd_id=0, operand_2_fd_id=0)] # save timestamp+1second actionSaveTimestamp = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_hf_id=1, operand_2_gd_id=1)] # Calculates EWMA on packet number actionEvaluateEWMA = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_MUL, output_fd_id=0, operand_1_fd_id=0, operand_2_cost=MULTIPLY_FACTOR), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_EWMA, output_fd_id=2, operand_1_fd_id=2, operand_2_cost=bebaproto.EWMA_PARAM_0875, operand_3_fd_id=0)] actionSetDSCPAttack = [ofparser.OFPActionSetField(ip_dscp=26)] actionSetDSCPNormal = [ofparser.OFPActionSetField(ip_dscp=13)] """ Measures and state transitions """ """ #T1_R1 """ """ First packet of a flow """ match = ofparser.OFPMatch(state=0, eth_type=0x800) actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0, idle_timeout=MONITORING_TIMEOUT)] + \ actionUpdateCounter + actionSaveTimestamp + actionSetDSCPNormal insts = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] + instGoto1 mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=50, match=match, instructions=insts) datapath.send_msg(mod) """ #T1_R2 """ """ State is MONITORING; in between the window ACTIONS: counter++ and set NORMAL DSCP info""" match = ofparser.OFPMatch(state=1, condition0=0, eth_type=0x800) actions = actionUpdateCounter + actionSetDSCPNormal insts = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] + instGoto1 mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=15, match=match, instructions=insts) datapath.send_msg(mod) """ #T1_R3 """ """ State is MONITORING; sampling time expired ACTIONS: evaluate EWMA, counter = 0, save new timestamp+SAMPLING""" match = ofparser.OFPMatch(state=1, condition0=1, eth_type=0x800) actions = actionEvaluateEWMA + actionResetCounter + actionSaveTimestamp insts = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] + instGoto1 mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=20, match=match, instructions=insts) datapath.send_msg(mod) """ #T1_R4 """ """ State is in MONITORING, the switch's own state is over threshold now ACTIONS: go to ATTACK state and trigger the control message """ match = ofparser.OFPMatch(state=1, condition2=1, eth_type=0x800) # apply mitigation policy actions = [bebaparser.OFPExpActionSetState(state=2, table_id=0)] + actionSetDSCPAttack insts = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] + instGoto1 mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=30, match=match, instructions=insts) datapath.send_msg(mod) """ #T1_R6 """ """ State is ATTACK, no more over threshold, either the sum of states or switch's own state""" match = ofparser.OFPMatch(state=2, condition2=0, eth_type=0x800) actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0, idle_timeout=MONITORING_TIMEOUT)] +\ actionSetDSCPNormal insts = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] + instGoto1 mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=100, match=match, instructions=insts) datapath.send_msg(mod) """ #T1_R7 """ """ State is ATTACK, monitor condition is valid""" match = ofparser.OFPMatch(state=2, condition0=0, eth_type=0x800) actions = actionUpdateCounter + actionSetDSCPAttack insts = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] + instGoto1 mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=50, match=match, instructions=insts) datapath.send_msg(mod) """ #T1_R8 """ """ State is ATTACK, window expired """ match = ofparser.OFPMatch(state=2, condition0=1, eth_type=0x800) actions = actionEvaluateEWMA + actionResetCounter + actionSaveTimestamp + actionSetDSCPAttack insts = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] + instGoto1 mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=50, match=match, instructions=insts) datapath.send_msg(mod) ######################## TAB 1: STATELESS ######################################## """ #T2_R3 """ # Pkts destined to host attached to switch match = ofparser.OFPMatch(eth_type=0x800, ipv4_dst=server_dict[datapath.id]) actions = [ofparser.OFPActionOutput(HOST_PORT)] self.add_flow(datapath=datapath, table_id=1, priority=70, match=match, actions=actions) # SW 2 """ #T2_R4-5 """ match = ofparser.OFPMatch(in_port=1, eth_type=0x800, ipv4_dst=addrs[3]) actions = [ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT)] self.add_flow(datapath=datapath, table_id=1, priority=50, match=match, actions=actions) match = ofparser.OFPMatch(in_port=2, eth_type=0x800, ipv4_dst=addrs[2]) actions = [ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT)] self.add_flow(datapath=datapath, table_id=1, priority=50, match=match, actions=actions) match = ofparser.OFPMatch(in_port=2, eth_type=0x800, ipv4_dst=addrs[3]) actions = [ofparser.OFPActionOutput(1)] self.add_flow(datapath=datapath, table_id=1, priority=50, match=match, actions=actions) match = ofparser.OFPMatch(in_port=1, eth_type=0x800, ipv4_dst=addrs[2]) actions = [ofparser.OFPActionOutput(2)] self.add_flow(datapath=datapath, table_id=1, priority=50, match=match, actions=actions) match = ofparser.OFPMatch(in_port=1, eth_type=0x800, ipv4_dst=addrs[1]) actions = [ofparser.OFPActionOutput(2)] self.add_flow(datapath=datapath, table_id=1, priority=50, match=match, actions=actions) match = ofparser.OFPMatch(in_port=2, eth_type=0x800, ipv4_dst=addrs[1]) actions = [ofparser.OFPActionOutput(1)] self.add_flow(datapath=datapath, table_id=1, priority=50, match=match, actions=actions)
def install_edge(self, datapath): """ Table 0 is stateless """ """ Set table 1 as stateful solo per usare GD""" req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=1, stateful=1) datapath.send_msg(req) """ Set table 3 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=3, stateful=1) datapath.send_msg(req) """ Set table 4 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=4, stateful=1) datapath.send_msg(req) """ Set table 5 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=5, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################ """ Tab1 """ """ Non mi interessa """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=1) datapath.send_msg(req) """ Non mi interessa """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=1) datapath.send_msg(req) """ Tab3 """ """ Set lookup extractor = {MPLS_label} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_MPLS_LABEL], table_id=3) datapath.send_msg(req) """ Set update extractor = {MPLS_label} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_MPLS_LABEL], table_id=3) datapath.send_msg(req) """ Tab4 """ """ Set lookup extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=4) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=4) datapath.send_msg(req) """ Tab5 """ """ Set lookup extractor = {MAC_DST} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_DST], table_id=5) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=5) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 1 ############################################ ''' GD[0] = datapath.id<<6 + numero crescente''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=1, global_data_variable_id=0, value=(datapath.id << 6) + 1) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 3 ############################################ ''' HF[0] = OXM_OF_MPLS_LABEL [id_pkt] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ''' GD[0] = 0 ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=0, value=0) datapath.send_msg(req) ''' GD[1] = datapath.id ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=1, value=0) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 4 ############################################ ''' HF[0] = OXM_OF_MPLS_LABEL [id_pkt] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=4, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=4, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ''' GD[0] = datapath.id ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=4, global_data_variable_id=0, value=1) datapath.send_msg(req) ########################### SET CONDITION TAB 4 ############################################ # condition 0: MPLS_TC <= COSTO MEMORIZZATO (FD[0]) ? # condition 0: HF[1] <= FD[0] ? req = osparser.OFPExpMsgSetCondition(datapath=datapath, table_id=4, condition_id=0, condition=osproto.CONDITION_LTE, operand_1_hf_id=1, operand_2_fd_id=0) datapath.send_msg(req) # condition 1: MPLS_TC <= 1 --> ovvero e il primo hop ? # condition 1: HF[1] <= GD[0] ? req = osparser.OFPExpMsgSetCondition(datapath=datapath, table_id=4, condition_id=1, condition=osproto.CONDITION_LTE, operand_1_hf_id=1, operand_2_gd_id=0) datapath.send_msg(req) ''' ####################### TAB 0 PushLabelMPLS ''' # Se il pacchetto proviene da una porta host (HOST_PORT) push label mpls e GOTO Tab 1 match = ofparser.OFPMatch(in_port=HOST_PORT) actions = [ofparser.OFPActionPushMpls()] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=8, match=match, instructions=inst) datapath.send_msg(mod) # Se proviene da un'altra porta ha gia la label MPLS GOTO Tab 1 giusto per dirlo esplicitamente perche ci andrebbe da solo CREDO NON DEVO FARE LA PushMpls match = ofparser.OFPMatch() actions = [] #se proviene da un altra porta ha gia la label MPLS inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 1 marca il pkt con ID_PKT ''' # Setta la label_mpls se non e gia stata configurata con il valore GD[0] + 1 -> (id_switch << 6) + 1 match = ofparser.OFPMatch(eth_type=0x8847, mpls_label=0) actions = [ osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_LABEL), osparser.OFPExpActionSetDataVariable(table_id=1, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_gd_id=0, operand_2_cost=1) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=8, match=match, instructions=inst) datapath.send_msg(mod) match = ofparser.OFPMatch(eth_type=0x8847) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=0, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 2 NULLA serve solo per i bug di OpenFlow, servono 2 stage xke le modifiche MPLS siano visibili''' # Non fa niente, ci sta solo per risolvere bug (presunti) di OpenFlow match = ofparser.OFPMatch(eth_type=0x8847) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=0, match=match, instructions=inst) datapath.send_msg(mod) '''####################### TAB 3 Verifica i duplicati, lo stato e' dato da mpls_label''' ''' somma il costo del link di ingresso al valore memorizzato nel pacchetto mpls_tc + 1 ''' ''' scrive il campo metada = 1 se e' un pacchetto duplicato ovvero nello stato 1 ''' """ Riga 1 """ # GD[0] = HF[1] + 1 -> MPLS_TC + 1 # HF [1] = GD[0] -> MPLS_TC = GD[0] # WriteMetadata = 1 -> pacchetto duplicato # SetState(1) # GOTO Tab 2 match = ofparser.OFPMatch(state=1, eth_type=0x8847) actions = [ osparser.OFPExpActionSetDataVariable(table_id=3, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_hf_id=1, operand_2_cost=1), osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_TC), # osparser.OFPExpActionSetState(state=1, table_id=3, idle_timeout=15)] osparser.OFPExpActionSetState(state=1, table_id=3) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=1, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=1198, match=match, instructions=inst) datapath.send_msg(mod) """ Riga 2 """ # GD[0] = HF[1] + 1 -> MPLS_TC + 1 # HF [1] = GD[0] -> MPLS_TC = GD[0] # SetState(1) # GOTO Tab 4 match = ofparser.OFPMatch(state=0, eth_type=0x8847) actions = [ osparser.OFPExpActionSetDataVariable(table_id=3, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_hf_id=1, operand_2_cost=1), osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_TC), # osparser.OFPExpActionSetState(state=1, table_id=3, idle_timeout=15)] osparser.OFPExpActionSetState(state=1, table_id=3) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=198, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 4 verifica le condizioni C[0] e C[1]''' ''' C[0] verifica se il costo memorizzato nel pacchetto e' <= di quello gia conosciuto (in pratica se il pacchetto ha fatto un percorso migliore) ''' ''' C[1] serve semplicemente a capire se e' lo switch direttametne collegato all'host che parla e quindi non bisogna fare il pop della label MPLS ''' ''' le righe BIS verificano la C[1] e non eseguono il POP della label MPLS ''' ''' metadata = 1 e' un pacchetto duplicato quindi DROP ''' ''' nel caso imposta metadata = 3 cioe' non e' un pacchetto duplicato ma il costo e' maggiore di quello conosciuto, inoltro senza aggiornare stato ''' """ Riga 1 """ # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0] # MetaData: 1 -> Pacchetto duplicato # azione DROP match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0, metadata=1) actions = [osparser.OFPExpActionSetState(state=1, table_id=4)] self.add_flow(datapath=datapath, table_id=4, priority=1198, match=match, actions=actions) """ Riga 2 """ # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0] # MetaData: 0 -> Pacchetto NON duplicato # SetState(1) # WriteMetadata = 3 -> pacchetto da percorso peggiore ma NON duplicato # azione GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0, condition1=0, metadata=0) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), ofparser.OFPActionPopMpls() ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=3, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=198, match=match, instructions=inst) datapath.send_msg(mod) """ Riga 2 BIS """ # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0] # MetaData: 0 -> Pacchetto NON duplicato # SetState(1) # WriteMetadata = 3 -> pacchetto da percorso peggiore ma NON duplicato # azione GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0, condition1=1, metadata=0) actions = [osparser.OFPExpActionSetState(state=1, table_id=4)] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=3, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=198, match=match, instructions=inst) datapath.send_msg(mod) """ Riga 3 """ # C[0]: MPLS_TC <= COSTO MEMORIZZATO -> HF[1] <= FD[0] # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC # SetState(1) # azione GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=1, condition1=0) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), ofparser.OFPActionPopMpls() ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=98, match=match, instructions=inst) datapath.send_msg(mod) """ Riga 3 BIS """ # C[0]: MPLS_TC <= COSTO MEMORIZZATO -> HF[1] <= FD[0] # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC # SetState(1) # azione GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=1, condition1=1) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=98, match=match, instructions=inst) datapath.send_msg(mod) """ Riga 4 """ # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC # SetState(1) # azione GOTO Tab 3 match = ofparser.OFPMatch(state=0, eth_type=0x8847, condition1=0) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), ofparser.OFPActionPopMpls() ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=8, match=match, instructions=inst) datapath.send_msg(mod) """ Riga 4 BIS """ # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC # SetState(1) # azione GOTO Tab 3 match = ofparser.OFPMatch(state=0, eth_type=0x8847, condition1=1) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=8, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 5 semplicemente MAC Learning ''' ''' Mac Learning ampliato per gestire i metadata = 1 o metadata = 3 ''' ''' metadata = 1 se e' arrivato fin qui significa che il costo nel pacchetto e' minore di quello conosciuto (ha seguito un percorso migliore) AGGIORNARE e DROP''' ''' metadata = 3 non e' un pacchetto duplicato ma il costo del percorso seguito e' peggiore di quello conosciuto NON AGGIORNARE e INOLTRA ''' # Per ogni input port, per ogni stato for i in range(1, N + 1): for s in range(N + 1): match = ofparser.OFPMatch(in_port=i, state=s) if s == 0: out_port = ofproto.OFPP_FLOOD #serve la flood, dipende se sto su S1 o S6 else: out_port = s # actions = [osparser.OFPExpActionSetState(state=i, table_id=5, hard_timeout=10), actions = [ osparser.OFPExpActionSetState(state=i, table_id=5), ofparser.OFPActionOutput(out_port) ] self.add_flow(datapath=datapath, table_id=5, priority=0, match=match, actions=actions) # Configuro le entry con azione DROP per i pacchetti duplicati (con metadata = 1) match = ofparser.OFPMatch(in_port=i, metadata=1) # actions = [osparser.OFPExpActionSetState(state=i, table_id=5, hard_timeout=10)] actions = [osparser.OFPExpActionSetState(state=i, table_id=5)] self.add_flow(datapath=datapath, table_id=5, priority=1198, match=match, actions=actions) # Per ogni stato for s in range(N + 1): match = ofparser.OFPMatch(state=s, metadata=3) if s == 0: out_port = ofproto.OFPP_FLOOD #serve la flood, dipende se sto su S1 o S6 else: out_port = s # Configuro le entry per l'output(in_port) senza aggiornare lo stato actions = [ofparser.OFPActionOutput(out_port)] self.add_flow(datapath=datapath, table_id=5, priority=198, match=match, actions=actions)
def switch_features_handler(self, event): """ switch sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) ########################################################################################### """ Set HF[1]=TIMESTAMP [ms] """ req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) """ Set GDV[3]=5500 """ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=3, value=3500) datapath.send_msg(req) """ Update function: FDV[0] = HF[1] + GDV[3] (i.e. deadline = now() + TIMEOUT) """ match = ofparser.OFPMatch(state=0) actions = [ ofparser.OFPActionOutput(ofproto.OFPP_FLOOD), bebaparser.OFPExpActionSetState(state=1, table_id=0), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_gd_id=3) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """ Set condition 3: HF[1] < FDV[0] (i.e. now() < deadline) """ req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, table_id=0, condition_id=3, condition=bebaproto.CONDITION_LT, operand_1_hf_id=1, operand_2_fd_id=0) datapath.send_msg(req) """ If now() < deadline then drop() """ match = ofparser.OFPMatch(state=1, condition3=1) actions = [ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """ If now() >= deadline then drop() & state transition """ match = ofparser.OFPMatch(state=1, condition3=0) actions = [ bebaparser.OFPExpActionSetState(state=2, table_id=0), ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """ drop() """ match = ofparser.OFPMatch(state=2) actions = [] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """
def switch_features_handler(self, event): """ switch sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) ########################################################################################### """ Set HF[1]=PKT_LEN [byte]""" req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) """ Set HF[2]=TIMESTAMP [ms]""" req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=2, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) """ GDV[0] = multiply factor for bit/s scale """ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=8) datapath.send_msg(req) """ Update function: ewma( [last ewma] , [alpha parameter] , [value to be averaged]) OUT1 = FDV[0] = count """ match = ofparser.OFPMatch() actions = [ #calculates deltaT: FDV[0]=HF[2]-FDV[0] = TS_NOW - TS_LAST bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=0, operand_1_hf_id=2, operand_2_fd_id=0), #multiply factor: FDV[1] = HF[1] * GD[0] = BYTES * 8000 bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_MUL, output_fd_id=1, operand_1_hf_id=1, operand_2_gd_id=0), #calculates rate: FDV[1]= FD[1]/FDV[0] = (BYTES*8000) / deltaT bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_DIV, output_fd_id=1, operand_1_fd_id=1, operand_2_fd_id=0), # Calculates EWMA on pkt/s bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_EWMA, output_fd_id=2, operand_1_fd_id=2, operand_2_cost=bebaproto.EWMA_PARAM_0875, operand_3_fd_id=1), #saves last TS: FDV[0] = HF[0] = timestamp bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=2, operand_2_cost=0), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """
def switch_features_handler(self, event): """ Switch sent his features, check if BEBA is supported. """ # Parse the datapath and remmber it as class variable msg = event.msg self.datapath = msg.datapath ######################################################################## ## Remove all entries from table 0,1 and 2 self.clear_table(self.datapath, 0) self.clear_table(self.datapath, 1) self.clear_table(self.datapath, 2) ######################################################################## ## Table 0 (main table) LOG.info("Configuring switch %d..." % self.datapath.id) LOG.info("Setting up Table 0 ...") # Set table 0 as stateful req = osparser.OFPExpMsgConfigureStatefulTable(datapath=self.datapath, table_id=0, stateful=1) self.datapath.send_msg(req) # Set lookup extractor = {ip_src, ip_dst, tcp_src, tcp_dst} TODO - proto=TCP?? req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_TCP_SRC, ofp.OXM_OF_TCP_DST ], table_id=0) self.datapath.send_msg(req) # Set update extractor = {ip_src, ip_dst, tcp_src, tcp_dst} req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_TCP_SRC, ofp.OXM_OF_TCP_DST ], table_id=0, bit=0) self.datapath.send_msg(req) req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_TCP_DST, ofp.OXM_OF_TCP_SRC ], table_id=0, bit=1) self.datapath.send_msg(req) LOG.info("Done.") ######################################################################## ## Table 1 (new TCP connection counter table) LOG.info("Setting up Table 1 ...") # Set table 1 as stateful req = osparser.OFPExpMsgConfigureStatefulTable(datapath=self.datapath, table_id=1, stateful=1) self.datapath.send_msg(req) # Set lookup extractor = {ip_dst} # use dst IP + dst Port??? req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_DST], table_id=1) self.datapath.send_msg(req) # Set update extractor = {ip_dst} req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_DST], table_id=1) self.datapath.send_msg(req) req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_DST], table_id=1, bit=1) self.datapath.send_msg(req) # Little hack, prepare table 2 to be used for counting, the table 2 contains default rule which # is used for sending of all unknown packets to the controller. match = ofparser.OFPMatch(eth_type=0x0800, ip_proto=6) actions = [ ofparser.OFPActionOutput(ofp.OFPP_CONTROLLER, ofp.OFPCML_NO_BUFFER) ] inst = [ ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions) ] mod = ofparser.OFPFlowMod(datapath=self.datapath, table_id=2, priority=0, match=match, instructions=inst) self.datapath.send_msg(mod) LOG.info("Done.") ################################################################################################### ## Set switches behavior - start default behavior and afterthat start the monitoring thread ## Enable "ping" command self.load_arp_icmp() ## Load FSM (table0) for normal mode of operation self.normal_FSM.load_fsm(self.datapath) ## Load FSM (table1) for counting of new tcp connections self.counter_FSM.load_fsm(self.datapath) ## Create a monitoring thread (each X seconds starst the statististics collection) self.monitor_thread = hub.spawn(self._monitor) LOG.info("Starting DDoS detection ...")
def install_leaves(self, datapath): ##################################### TABLE 0: DISPATCHING ################################################## ######################### TABLE 0 CONFIG ############### req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) """ Field extractor for mpls label """ req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) """ Field extractor for timestamp """ req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) """ Packet counter_max for designing probe frequency """ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=9) datapath.send_msg(req) """ Condition C0: if counter reaches counter_max, then trigger probe sending """ req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, table_id=0, condition_id=0, condition=bebaproto.CONDITION_GTE, operand_1_fd_id=0, operand_2_gd_id=0) datapath.send_msg(req) req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, table_id=0, condition_id=3, condition=bebaproto.CONDITION_GTE, operand_1_fd_id=0, operand_2_gd_id=0) datapath.send_msg(req) ##################################### TABLE 0 FLOWS ################################################## """ RECEIVE PROBE ACTION """ """ When a probe is received tab0 sends it to tab3""" """ match: MPLS """ """ no action """ """ instruction: goto tab3""" match = ofparser.OFPMatch(eth_type=0x8847) instructions = [ofparser.OFPInstructionGotoTable(3)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=200, match=match, instructions=instructions) datapath.send_msg(mod) for i in UPPER_PORTS: """ Writes metadata 1 if C0 is true (i.e. if it's time to send probe) to inform the Util Table (2) """ match = ofparser.OFPMatch(in_port=i, condition0=1) actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=0, operand_1_fd_id=0, operand_2_gd_id=0), ofparser.OFPActionPushMpls() ] #push mpls for tab 2 instructions = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=1, metadata_mask=0xffffffff), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=50, match=match, instructions=instructions) datapath.send_msg(mod) """ If C0 is false, update the counter (i++) and go to Util Table for ewma measuring """ match = ofparser.OFPMatch(in_port=i, condition0=0) actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_fd_id=0, operand_2_cost=1) ] instructions = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=30, match=match, instructions=instructions) datapath.send_msg(mod) """ For packets from down ports (attached to hosts): go to ToR Discovery table (1) """ for i in DOWN_PORTS: match = ofparser.OFPMatch(in_port=i) instructions = [ofparser.OFPInstructionGotoTable(1)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=instructions) datapath.send_msg(mod) for i in [0, 1]: match = ofparser.OFPMatch(in_port=3, eth_type=0x0800, ip_proto=6, tcp_dst=10000 + i) actions = [ofparser.OFPActionOutput(i + 1)] self.add_flow(datapath=datapath, table_id=0, priority=200, match=match, actions=actions) match = ofparser.OFPMatch(in_port=3, eth_type=0x0800, ip_proto=6, tcp_src=10000 + i) actions = [ofparser.OFPActionOutput(i + 1)] self.add_flow(datapath=datapath, table_id=0, priority=200, match=match, actions=actions) ######################## TABLE 1 ToR DISCOVERY ######################################################### # this cycle writes metadata specifying to which leaf belongs the packet for i in LEAVES: if (i != datapath.id): match = ofparser.OFPMatch(eth_dst=MAC_ADDRS[i - 1]) instructions = [ ofparser.OFPInstructionWriteMetadata( metadata=i, metadata_mask=0xffffffff), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=0, match=match, instructions=instructions) datapath.send_msg(mod) ######################### TABLE 2: ACTIVE PROBING ###################################################### ################### TABLE 2 CONFIG ######### req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=2, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {IN_PORT} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=2) datapath.send_msg(req) """ Set update extractor = {IN_PORT} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=2) datapath.send_msg(req) # multiply factor: convert to kbit/s req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=2, global_data_variable_id=0, value=8000) datapath.send_msg(req) # number of averaging samples req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=2, global_data_variable_id=3, value=40) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=2, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=0, table_id=2, operand_1_fd_id=4, operand_2_gd_id=3) datapath.send_msg(req) ############################### TABLE 2 FLOWS ############################# """ For every packet coming from spine ports, calculates ewma """ for i in UPPER_PORTS: #simply ewma measuring match = ofparser.OFPMatch(in_port=i, condition0=1) actions_ewma_1 = [ #calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUB, output_fd_id=1, operand_1_hf_id=1, operand_2_fd_id=0), #calculates rate: R = (bytes / deltaT_us) * 1000 kB/s bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_MUL, output_fd_id=2, operand_1_fd_id=2, operand_2_gd_id=0), #stores the result in FDV[3]: THE FLOW ESTIMATED RATE bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_DIV, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=1), #calculates ewma bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_EWMA, output_fd_id=3, operand_1_fd_id=3, operand_2_cost=bebaproto.EWMA_PARAM_0250, operand_3_fd_id=2), #saves current timestamp bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), #counter returns to zero bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUB, output_fd_id=4, operand_1_fd_id=4, operand_2_fd_id=4), # saves in GDV[i] the ewma bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_gd_id=i, operand_1_fd_id=3, operand_2_cost=0) ] self.add_flow(datapath=datapath, table_id=2, priority=30, match=match, actions=actions_ewma_1 + [ofparser.OFPActionOutput(3)]) match = ofparser.OFPMatch(in_port=i, condition0=0) actions_ewma_2 = [ bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_fd_id=2, operand_2_hf_id=2), bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_fd_id=4, operand_2_cost=1) ] self.add_flow(datapath=datapath, table_id=2, priority=30, match=match, actions=actions_ewma_2 + [ofparser.OFPActionOutput(3)]) """ PROBES: When it matches metadata=1 it means that this packet has to be duplicated to piggyback on it the probe """ #group mod for packet duplication and probing buckets = [] actions1 = [ ofparser.OFPActionSetField(mpls_tc=datapath.id), #the GDV[i] bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=i, dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT) ] buckets.append(ofparser.OFPBucket(actions=actions1)) actions1 = [ ofparser.OFPActionSetField( mpls_tc=datapath.id), #the GDV[other] bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=(1 if i == 2 else 2), dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput((1 if i == 2 else 2)) ] buckets.append(ofparser.OFPBucket(actions=actions1)) req = ofparser.OFPGroupMod(datapath=datapath, type_=ofproto.OFPGT_ALL, group_id=i, buckets=buckets) datapath.send_msg(req) # actual match and actions: group action, popMpls() and output(3) match = ofparser.OFPMatch(in_port=i, eth_type=0x8847, metadata=1) actions = [ ofparser.OFPActionGroup(i), ofparser.OFPActionPopMpls(), ofparser.OFPActionOutput(3) ] self.add_flow(datapath=datapath, table_id=2, priority=100, match=match, actions=actions) for j in [0, 1]: match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_dst=10000 + j, condition0=1) actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_src=10000 + j, condition0=1) actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_dst=10000 + j, condition0=0) actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_src=10000 + j, condition0=0) actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) ######################## TABLE 3: FORWARDING ############################################################## ######################## TABLE 3 CONFIG ##################################################################### ##### GDV[1] contains path utilization to dest 1 on port 1 ##### GDV[2] contains path utilization to dest 2 on port 1 ##### GDV[3] contains path utilization to dest 1 on port 2 ##### GDV[4] contains path utilization to dest 2 on port 2 req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=3, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {ETH_DST IP_PROTO TCP_DST} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST ], table_id=3) datapath.send_msg(req) """ Set update extractor = {} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST ], table_id=3) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=2, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) # GDV[0] = multiply factor req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=0, value=8000) datapath.send_msg(req) # GDV[6] = packets needed for average req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=6, value=40 - 1) datapath.send_msg(req) # GDV[5] = elephant flow threshold req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=5, value=2000) # 2000 kb/s datapath.send_msg(req) # Lower flow threshold req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=7, value=300) datapath.send_msg(req) for i in [1, 2, 3]: req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=i, value=0) datapath.send_msg(req) #################################### TABLE 3 FLOWS ################################### # many conditions as the number of LEAVES-1 # for i in LEAVES except datapath.id: create condition[i] # in the case of 2 Spines. For more spines the configuration becomes more complex for destLeaf in [1, 2]: # C[destinationLeaf]: which port is less utilized? req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_LTE, condition_id=destLeaf, table_id=3, operand_1_gd_id=destLeaf, operand_2_gd_id=destLeaf + 2) datapath.send_msg(req) # C[0], has the flow exceeded threshold? i.e. flow_rate >= threshold => FDV[3] >= GDV[5] req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=0, table_id=3, operand_1_fd_id=3, operand_2_gd_id=5) datapath.send_msg(req) # C[3], is the other flow lower than a value? FDV[4] < GDV[7] ? req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_LTE, condition_id=3, table_id=3, operand_1_fd_id=4, operand_2_gd_id=7) datapath.send_msg(req) # C[4]: did the counter reach counterMax? FDV[5] = GDV[6] ? req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_EQ, condition_id=4, table_id=3, operand_1_fd_id=5, operand_2_gd_id=6) datapath.send_msg(req) # leaf number dependent flows if datapath.id == 1: #LEAF 1 new flows: fetch the destination leaf and check the appropriate condition match1true = ofparser.OFPMatch(metadata=2, condition1=1, state=0) #dst=2, port 1 match2true = ofparser.OFPMatch(metadata=3, condition2=1, state=0) #dst=3, port 1 match1false = ofparser.OFPMatch(metadata=2, condition1=0, state=0) #dst=2, port 2 match2false = ofparser.OFPMatch(metadata=3, condition2=0, state=0) #dst=3, port 2 elif datapath.id == 2: #LEAF 2 new flows: fetch the destination leaf and check the appropriate condition match1true = ofparser.OFPMatch(metadata=1, condition1=1, state=0) #dst=1, port 1 match2true = ofparser.OFPMatch(metadata=3, condition2=1, state=0) #dst=3, port 1 match1false = ofparser.OFPMatch(metadata=1, condition1=0, state=0) #dst=1, port 2 match2false = ofparser.OFPMatch(metadata=3, condition2=0, state=0) #dst=3, port 2 elif datapath.id == 3: #LEAF 3 new flows: fetch the destination leaf and check the appropriate condition match1true = ofparser.OFPMatch(metadata=1, condition1=1, state=0) #dst=1, port 1 match2true = ofparser.OFPMatch(metadata=2, condition2=1, state=0) #dst=2, port 1 match1false = ofparser.OFPMatch(metadata=1, condition1=0, state=0) #dst=1, port 2 match2false = ofparser.OFPMatch(metadata=2, condition2=0, state=0) #dst=2, port 2 #if port 1 is better, set_state(1) and output 1 actions_true = [ bebaparser.OFPExpActionSetState(state=1, table_id=3, idle_timeout=5), ofparser.OFPActionOutput(1) ] #if port 2 is better, set_state(2) and output 2 actions_false = [ bebaparser.OFPExpActionSetState(state=2, table_id=3, idle_timeout=5), ofparser.OFPActionOutput(2) ] self.add_flow(datapath=datapath, table_id=3, priority=20, match=match1true, actions=actions_true) self.add_flow(datapath=datapath, table_id=3, priority=20, match=match2true, actions=actions_true) self.add_flow(datapath=datapath, table_id=3, priority=20, match=match1false, actions=actions_false) self.add_flow(datapath=datapath, table_id=3, priority=20, match=match2false, actions=actions_false) """ extract external probes' data and store in GDVs """ match = ofparser.OFPMatch(eth_type=0x8847, mpls_tc=datapath.id) self.add_flow(datapath=datapath, table_id=3, priority=300, match=match, actions=[]) for i in UPPER_PORTS: for leafNo in LEAVES: match = ofparser.OFPMatch(in_port=i, eth_type=0x8847, mpls_tc=leafNo) """ actions: save in GDVs external probes' data """ if datapath.id == 1: if leafNo == 2: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(1 if i == 1 else 3), operand_1_hf_id=0, operand_2_cost=0) ] elif leafNo == 3: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(2 if i == 1 else 4), operand_1_hf_id=0, operand_2_cost=0) ] elif datapath.id == 2: if leafNo == 1: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(1 if i == 1 else 3), operand_1_hf_id=0, operand_2_cost=0) ] elif leafNo == 3: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(2 if i == 1 else 4), operand_1_hf_id=0, operand_2_cost=0) ] elif datapath.id == 3: if leafNo == 1: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(1 if i == 1 else 3), operand_1_hf_id=0, operand_2_cost=0) ] elif leafNo == 2: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(2 if i == 1 else 4), operand_1_hf_id=0, operand_2_cost=0) ] self.add_flow(datapath=datapath, table_id=3, priority=200, match=match, actions=actions) for s in UPPER_PORTS: for metadata in LEAVES: # normal conditions, installed flows continue flowing, calculates ewma if counter reaches max match = ofparser.OFPMatch(in_port=3, state=s, metadata=metadata, condition4=1) actions_ewma = [ #calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUB, output_fd_id=1, operand_1_hf_id=1, operand_2_fd_id=0), #calculates rate: R = (bytes / deltaT_us) * 1000 kB/s bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_MUL, output_fd_id=2, operand_1_fd_id=2, operand_2_gd_id=0), #stores the result in FDV[3]: THE FLOW ESTIMATED RATE bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_DIV, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=1), #calculates ewma bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_EWMA, output_fd_id=3, operand_1_fd_id=3, operand_2_cost=bebaproto.EWMA_PARAM_0250, operand_3_fd_id=2), #saves current timestamp bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), #counter returns to zero bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUB, output_fd_id=5, operand_1_fd_id=5, operand_2_fd_id=5) ] # FDV[4] = flow's alternative path utilization if datapath.id == 1: if metadata == 2: actions_ewma += [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_gd_id=(1 if s == 2 else 3), operand_2_cost=0) ] elif metadata == 3: actions_ewma += [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_gd_id=(2 if s == 2 else 4), operand_2_cost=0) ] elif datapath.id == 2: if metadata == 1: actions_ewma += [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_gd_id=(1 if s == 2 else 3), operand_2_cost=0) ] elif metadata == 3: actions_ewma += [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_gd_id=(2 if s == 2 else 4), operand_2_cost=0) ] elif datapath.id == 3: if metadata == 1: actions_ewma += [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_gd_id=(1 if s == 2 else 3), operand_2_cost=0) ] elif metadata == 2: actions_ewma += [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_gd_id=(2 if s == 2 else 4), operand_2_cost=0) ] actions = actions_ewma + [ofparser.OFPActionOutput(s)] self.add_flow(datapath=datapath, table_id=3, priority=30, match=match, actions=actions) # normal conditions match = ofparser.OFPMatch(in_port=3, state=s, metadata=metadata, condition4=0) actions_ewma_bg = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_fd_id=2, operand_2_hf_id=2), bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=5, operand_1_fd_id=5, operand_2_cost=1) ] actions = actions_ewma_bg + [ofparser.OFPActionOutput(s)] self.add_flow(datapath=datapath, table_id=3, priority=30, match=match, actions=actions) ########### match for extended states: same thing as in normal states but evaluate condition0 ########## match = ofparser.OFPMatch(in_port=3, state=s + (1 << 5), metadata=metadata, condition0=1, condition4=1) actions = actions_ewma + [ofparser.OFPActionOutput(s)] self.add_flow(datapath=datapath, table_id=3, priority=35, match=match, actions=actions) match = ofparser.OFPMatch(in_port=3, state=s + (1 << 5), metadata=metadata, condition0=1, condition4=0) actions = actions_ewma_bg + [ofparser.OFPActionOutput(s)] self.add_flow(datapath=datapath, table_id=3, priority=35, match=match, actions=actions) ############# condition[0] and [3] are verified, (i.e. big flow) change port ########### match = ofparser.OFPMatch(in_port=3, state=s, condition0=1, condition3=1) actions = [ bebaparser.OFPExpActionSetState( state=(1 if s == 2 else 2) + (1 << 5), table_id=3, idle_timeout=5), ofparser.OFPActionOutput(1 if s == 2 else 2) ] self.add_flow(datapath=datapath, table_id=3, priority=40, match=match, actions=actions) ########### if the flow returns to a rate under the threshold ############################# match = ofparser.OFPMatch(in_port=3, state=s + (1 << 5), condition0=0) actions = [ bebaparser.OFPExpActionSetState(state=s, table_id=3, idle_timeout=5), ofparser.OFPActionOutput(s) ] self.add_flow(datapath=datapath, table_id=3, priority=50, match=match, actions=actions)
def install_spines(self, datapath): ######################### TABLE 1 CONFIG ############### req = bebaparser.OFPExpMsgConfigureStatefulTable( datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) # multiply factor req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=8000) datapath.send_msg(req) # averaging points req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=1, value=AVG_SAMPLES) datapath.send_msg(req) # mpls extractor req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL ) datapath.send_msg(req) # timestamp req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP ) datapath.send_msg(req) # packet lenght req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=2, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=0, table_id=0, operand_1_fd_id=4, operand_2_gd_id=1) datapath.send_msg(req) ########################### TABLE 1: MEASURING ##################### for i in LEAVES: if i == 1: out_ports = [6, 7] elif i == 2: out_ports = [5, 7] elif i == 3: out_ports = [5, 6] buckets = [] actions = [ bebaparser.OFPExpActionWriteContextToField(src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=3, dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput(out_ports[0] - 4)] buckets.append(ofparser.OFPBucket(actions=actions)) actions = [ bebaparser.OFPExpActionWriteContextToField(src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=4, dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput(out_ports[1] - 4)] buckets.append(ofparser.OFPBucket(actions=actions)) # send the group action req = ofparser.OFPGroupMod(datapath=datapath, type_=ofproto.OFPGT_ALL, group_id=i, buckets=buckets) datapath.send_msg(req) match = ofparser.OFPMatch(in_port=i, eth_type=0x8847) actions = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=3, operand_1_hf_id=0, operand_2_gd_id=out_ports[0]), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=4, operand_1_hf_id=0, operand_2_gd_id=out_ports[1]), ofparser.OFPActionGroup(i)] self.add_flow(datapath=datapath, priority=100, table_id=0, match=match, actions=actions) # simple forwarding packets go to second table to forward match = ofparser.OFPMatch(in_port=i, condition0=1) actions = [ # calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=1, operand_1_hf_id=1, operand_2_fd_id=0), # calculates rate: R = (bytes / deltaT_us) * 1000 kB/s bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_MUL, output_fd_id=2, operand_1_fd_id=2, operand_2_gd_id=0), # stores the result in FDV[3]: THE FLOW ESTIMATED RATE bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_DIV, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=1), # calculates ewma bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_EWMA, output_fd_id=3, operand_1_fd_id=3, operand_2_cost=bebaproto.EWMA_PARAM_0375, operand_3_fd_id=2), # saves current timestamp bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), # counter returns to zero bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=4, operand_1_fd_id=4, operand_2_fd_id=4), # saves in GDV[i+4] the ewma port[1,2,3]->[5,6,7] bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=i + 4, operand_1_fd_id=3, operand_2_cost=0)] instructions = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1)] mod = ofparser.OFPFlowMod(datapath=datapath, priority=0, table_id=0, match=match, instructions=instructions) datapath.send_msg(mod) match = ofparser.OFPMatch(in_port=i, condition0=0) actions = [bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_fd_id=2, operand_2_hf_id=2), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_fd_id=4, operand_2_cost=1)] instructions = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1)] mod = ofparser.OFPFlowMod(datapath=datapath, priority=0, table_id=0, match=match, instructions=instructions) datapath.send_msg(mod) ######################## TABLE 2: FORWARDING ################ for i in LEAVES: match = ofparser.OFPMatch(eth_dst=MAC_ADDRS[i - 1]) actions = [ofparser.OFPActionOutput(i)] self.add_flow(datapath=datapath, table_id=1, priority=0, match=match, actions=actions)
def install_edge(self, datapath): """ Table 0 is stateless """ """ Set table 1 as stateful for GD""" req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=1, stateful=1) datapath.send_msg(req) """ Set table 3 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=3, stateful=1) datapath.send_msg(req) """ Set table 4 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=4, stateful=1) datapath.send_msg(req) """ Set table 5 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=5, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################ """ Tab1 """ """ Don't care """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=1) datapath.send_msg(req) """ Don't care """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=1) datapath.send_msg(req) """ Tab3 """ """ Set lookup extractor = {MPLS_label} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_MPLS_LABEL], table_id=3) datapath.send_msg(req) """ Set update extractor = {MPLS_label} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_MPLS_LABEL], table_id=3) datapath.send_msg(req) """ Tab4 """ """ Set lookup extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=4) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=4) datapath.send_msg(req) """ Tab5 """ """ Set lookup extractor = {MAC_DST} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_DST], table_id=5) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=5) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 1 ############################################ ''' GD[0] = datapath.id<<6 + sequence number''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=1, global_data_variable_id=0, value=(datapath.id << 6) + 1) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 3 ############################################ ''' HF[0] = OXM_OF_MPLS_LABEL [id_pkt] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) ''' HF[1] = OXM_OF_MPLS_TC [linkWeight] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ''' GD[0] = 0 ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=0, value=0) datapath.send_msg(req) ''' GD[1] = datapath.id ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=1, value=0) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 4 ############################################ ''' HF[0] = OXM_OF_MPLS_LABEL [id_pkt] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=4, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) ''' HF[1] = OXM_OF_MPLS_TC [linkWeight] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=4, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ''' GD[0] = datapath.id ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=4, global_data_variable_id=0, value=1) datapath.send_msg(req) ########################### SET CONDITION TAB 4 ############################################ # condition 0: MPLS_TC <= KNOWN WEIGHT (FD[0]) # condition 0: HF[1] <= FD[0] ? req = osparser.OFPExpMsgSetCondition(datapath=datapath, table_id=4, condition_id=0, condition=osproto.CONDITION_LTE, operand_1_hf_id=1, operand_2_fd_id=0) datapath.send_msg(req) # condition 1: MPLS_TC <= 1 --> first hop # condition 1: HF[1] <= GD[0] ? req = osparser.OFPExpMsgSetCondition(datapath=datapath, table_id=4, condition_id=1, condition=osproto.CONDITION_LTE, operand_1_hf_id=1, operand_2_gd_id=0) datapath.send_msg(req) ''' ####################### TAB 0 PushLabelMPLS ''' # Input from host port (HOST_PORT) push label mpls e GOTO Tab 1 match = ofparser.OFPMatch(in_port=HOST_PORT) actions = [ofparser.OFPActionPushMpls()] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=8, match=match, instructions=inst) datapath.send_msg(mod) match = ofparser.OFPMatch() actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 1 mark pkt with ID_PKT ''' # Set label_mpls: GD[0] + 1 -> (id_switch << 6) + 1 match = ofparser.OFPMatch(eth_type=0x8847, mpls_label=0) actions = [ osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_LABEL), osparser.OFPExpActionSetDataVariable(table_id=1, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_gd_id=0, operand_2_cost=1) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=8, match=match, instructions=inst) datapath.send_msg(mod) match = ofparser.OFPMatch(eth_type=0x8847) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=0, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 2 ''' match = ofparser.OFPMatch(eth_type=0x8847) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=0, match=match, instructions=inst) datapath.send_msg(mod) '''####################### TAB 3 Check duplicate, State: mpls_label''' """ Line 1 """ # GD[0] = HF[1] + 1 -> MPLS_TC + 1 # HF [1] = GD[0] -> MPLS_TC = GD[0] # WriteMetadata = 1 -> duplicate pkt # SetState(1) # GOTO Tab 2 match = ofparser.OFPMatch(state=1, eth_type=0x8847) actions = [ osparser.OFPExpActionSetDataVariable(table_id=3, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_hf_id=1, operand_2_cost=1), osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_TC), # osparser.OFPExpActionSetState(state=1, table_id=3, idle_timeout=15)] osparser.OFPExpActionSetState(state=1, table_id=3) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=1, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=1198, match=match, instructions=inst) datapath.send_msg(mod) """ Line 2 """ # GD[0] = HF[1] + 1 -> MPLS_TC + 1 # HF [1] = GD[0] -> MPLS_TC = GD[0] # SetState(1) # GOTO Tab 4 match = ofparser.OFPMatch(state=0, eth_type=0x8847) actions = [ osparser.OFPExpActionSetDataVariable(table_id=3, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_hf_id=1, operand_2_cost=1), osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_TC), osparser.OFPExpActionSetState(state=1, table_id=3) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=198, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 4 check condition C[0] e C[1]''' """ Line 1 """ # C[0]: MPLS_TC > KNOWN WEIGHT -> HF[1] > FD[0] # MetaData: 1 -> duplicate pkt # action DROP match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0, metadata=1) actions = [osparser.OFPExpActionSetState(state=1, table_id=4)] self.add_flow(datapath=datapath, table_id=4, priority=1198, match=match, actions=actions) """ Line 2 """ # C[0]: MPLS_TC > KNOWN WEIGHT -> HF[1] > FD[0] # MetaData: 0 -> NOT duplicate # SetState(1) # WriteMetadata = 3 -> WORSE PATH, NOT duplicate # action GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0, condition1=0, metadata=0) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), ofparser.OFPActionPopMpls() ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=3, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=198, match=match, instructions=inst) datapath.send_msg(mod) """ Line 2 BIS """ # C[0]: MPLS_TC > KNOWN WEIGHT -> HF[1] > FD[0] # MetaData: 0 -> NOT duplicate # SetState(1) # WriteMetadata = 3 -> WORSE PATH, NOT duplicate # action GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0, condition1=1, metadata=0) actions = [osparser.OFPExpActionSetState(state=1, table_id=4)] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=3, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=198, match=match, instructions=inst) datapath.send_msg(mod) """ Line 3 """ # C[0]: MPLS_TC <= KNOWN WEIGHT -> HF[1] <= FD[0] # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC # SetState(1) # action GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=1, condition1=0) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), ofparser.OFPActionPopMpls() ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=98, match=match, instructions=inst) datapath.send_msg(mod) """ Line 3 BIS """ # C[0]: MPLS_TC <= KNOWN WEIGHT -> HF[1] <= FD[0] # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC # SetState(1) # action GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=1, condition1=1) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=98, match=match, instructions=inst) datapath.send_msg(mod) """ Line 4 """ # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC # SetState(1) # action GOTO Tab 3 match = ofparser.OFPMatch(state=0, eth_type=0x8847, condition1=0) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), ofparser.OFPActionPopMpls() ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=8, match=match, instructions=inst) datapath.send_msg(mod) """ Line 4 BIS """ # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC # SetState(1) # action GOTO Tab 3 match = ofparser.OFPMatch(state=0, eth_type=0x8847, condition1=1) actions = [ osparser.OFPExpActionSetState(state=1, table_id=4), osparser.OFPExpActionSetDataVariable(table_id=4, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(5) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=4, priority=8, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 5 simply MAC Learning ''' ''' Mac Learning, check if metadata = 1 or metadata = 3 ''' # For each input port, for each state for i in range(1, N + 1): for s in range(N + 1): match = ofparser.OFPMatch(in_port=i, state=s) if s == 0: out_port = ofproto.OFPP_FLOOD else: out_port = s # actions = [osparser.OFPExpActionSetState(state=i, table_id=5, hard_timeout=10), actions = [ osparser.OFPExpActionSetState(state=i, table_id=5), ofparser.OFPActionOutput(out_port) ] self.add_flow(datapath=datapath, table_id=5, priority=0, match=match, actions=actions) # DROP duplicate pkt (metadata = 1) match = ofparser.OFPMatch(in_port=i, metadata=1) # actions = [osparser.OFPExpActionSetState(state=i, table_id=5, hard_timeout=10)] actions = [osparser.OFPExpActionSetState(state=i, table_id=5)] self.add_flow(datapath=datapath, table_id=5, priority=1198, match=match, actions=actions) # For each state for s in range(N + 1): match = ofparser.OFPMatch(state=s, metadata=3) if s == 0: out_port = ofproto.OFPP_FLOOD else: out_port = s actions = [ofparser.OFPActionOutput(out_port)] self.add_flow(datapath=datapath, table_id=5, priority=198, match=match, actions=actions)
def install_transport_bad(self, datapath): """ Set table 0 as stateful for GD """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set table 2 as stateful, check condition path""" req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=2, stateful=1) datapath.send_msg(req) """ Set table 3 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=3, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################ """ Tab0 """ """ Don't care """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Don't care """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Tab2 """ """ Set lookup extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=2) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=2) datapath.send_msg(req) """ Tab3 """ """ Set lookup extractor = {MAC_DST} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_DST], table_id=3) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=3) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 0 ############################################ ''' HF[1] = OXM_OF_MPLS_TC [linkWeight] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ''' GD[0] = 0 ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=0) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 2 ############################################ ''' HF[1] = OXM_OF_MPLS_TC [linkWeight] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ########################### SET CONDITION TAB 2 ############################################ # condition 3: MPLS_TC <= KNOWN WEIGHT (FD[0]) ? # condition 3: HF[1] <= FD[0] ? req = osparser.OFPExpMsgSetCondition(datapath=datapath, table_id=2, condition_id=0, condition=osproto.CONDITION_LTE, operand_1_hf_id=1, operand_2_fd_id=0) datapath.send_msg(req) '''####################### TAB 0 ''' """ Line 1 """ # GD[0] = HF[1] + 1 -> MPLS_TC + 1 # HF [1] = GD[0] -> MPLS_TC = GD[0] # GOTO Tab 2 match = ofparser.OFPMatch(eth_type=0x8847) actions = [ osparser.OFPExpActionSetDataVariable(table_id=0, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_hf_id=1, operand_2_cost=2), osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_TC) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=1198, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 1 ''' match = ofparser.OFPMatch(eth_type=0x8847) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=0, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 2 ''' """ Line 1 """ # C[0]: MPLS_TC > KNOWN WEIGHT -> HF[1] > FD[0] # MetaData: 1 -> Duplicate pkt # action DROP match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0) actions = [osparser.OFPExpActionSetState(state=1, table_id=2)] self.add_flow(datapath=datapath, table_id=2, priority=198, match=match, actions=actions) """ Line 2 """ # C[0]: MPLS_TC <= KNOWN WEIGHT -> HF[1] <= FD[0] # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC # SetState(1) # action GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=1) actions = [ osparser.OFPExpActionSetState(state=1, table_id=2), osparser.OFPExpActionSetDataVariable(table_id=2, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=98, match=match, instructions=inst) datapath.send_msg(mod) """ Line 3 """ # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC # SetState(1) # action GOTO Tab 3 match = ofparser.OFPMatch(state=0, eth_type=0x8847) actions = [ osparser.OFPExpActionSetState(state=1, table_id=2), osparser.OFPExpActionSetDataVariable(table_id=2, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=8, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 3 simply MAC Learning ''' # for each input port, for each state for i in range(1, N + 1): for s in range(N + 1): match = ofparser.OFPMatch(in_port=i, state=s) if s == 0: out_port = ofproto.OFPP_FLOOD else: out_port = s # actions = [osparser.OFPExpActionSetState(state=i, table_id=3, hard_timeout=10), actions = [ osparser.OFPExpActionSetState(state=i, table_id=3), ofparser.OFPActionOutput(out_port) ] self.add_flow(datapath=datapath, table_id=3, priority=0, match=match, actions=actions)
def switch_features_handler(self, event): """ switch sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {ip_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC], table_id=0) datapath.send_msg(req) """ Set update extractor = {ip_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC], table_id=0) datapath.send_msg(req) ########################################################################################### # Constants B = 20 # token R = 1 # token/sec ''' Assuming B=20 initial tokens and R=1 token/sec mininet> h1 ping h2 -i 0.1 [20 tk + 1 tk/s * X ] - [10 tk/s * X] = 0 We expect to start losing 9 packet out of 10 after 2.22 sec (starting from around 22th packet) Now close and re-open the switch mininet> h1 ping h2 -i 0.25 [20 tk + 1 tk/s * X ] - [4 tk/s * X] = 0 We expect to start losing 3 packet out of 4 after 6.66 sec (starting from around 26th packet) Now close and re-open the switch mininet> h1 ping h2 -i 0.5 [20 tk + 1 tk/s * X ] - [2 tk/s * X] = 0 We expect to start losing 1 packet out of 2 after 20 sec (starting from around 40th packet) ''' ''' HF[0] = OXM_EXP_TIMESTAMP [ms] ''' req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=0, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) ''' GD[0] = (B-1)*(1/R)*1000 [tok]*[1000 msec/tok]* ''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=int((B - 1) * (1 / float(R) * 1000))) datapath.send_msg(req) ''' GD[1] = (1/R)*1000 [msec]* ''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=1, value=int((1 / float(R) * 1000))) datapath.send_msg(req) # condition 0: HF[0] >= FDV[0] ? # condition 0: now >= Tmin ? req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, table_id=0, condition_id=0, condition=bebaproto.CONDITION_GTE, operand_1_hf_id=0, operand_2_fd_id=0) datapath.send_msg(req) # condition 1: HF[0] <= FDV[2] ? # condition 1: now - Tmin <= (B-1)*(1/R) ? req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, table_id=0, condition_id=1, condition=bebaproto.CONDITION_LTE, operand_1_hf_id=0, operand_2_fd_id=2) datapath.send_msg(req) # FDV[0] = now()-(B-1)*(1/R) = now() - GDV[0] = Tmin # FDV[1] = 0 + GDV[1] = 1/R in ms # FDV[2] = HF[0] + GDV[1] = now() + 1/R match = ofparser.OFPMatch(eth_type=0x0800, state=0) actions = [ bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=0, operand_1_hf_id=0, operand_2_gd_id=0), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_fd_id=1, operand_2_gd_id=1), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_hf_id=0, operand_2_gd_id=1), bebaparser.OFPExpActionSetState(state=1, table_id=0), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) # FDV[0] = FDV[0]+FDV[1] # FDV[2] = FDV[2]+FDV[1] match = ofparser.OFPMatch(eth_type=0x0800, state=1, condition0=1, condition1=1) actions = [ bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_fd_id=0, operand_2_fd_id=1), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=1), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) # FDV[0] = now()-(B-1)*(1/R) = now() - GDV[0] = Tmin # FDV[2] = HF[0] + GDV[1] = now() + 1/R match = ofparser.OFPMatch(eth_type=0x0800, state=1, condition0=1, condition1=0) actions = [ bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=0, operand_1_hf_id=0, operand_2_gd_id=0), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_hf_id=0, operand_2_gd_id=1), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) match = ofparser.OFPMatch(eth_type=0x0800, state=1, condition0=0, condition1=1) actions = [] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions)
def switch_features_handler(self, event): """ Switche sent his features, check if OpenState supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {src ip} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osp.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_IPV4_DST], table_id=0, bit=0) datapath.send_msg(req) """ Set update extractor = {dst ip} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_IPV4_DST], table_id=0, bit=0) datapath.send_msg(req) req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_IPV4_SRC], table_id=0, bit=1) datapath.send_msg(req) # Try to install rule with TCP flag LOG.info("Confiuguring Flow table ...") match = ofparser.OFPMatch(state=0, eth_type=0x0800, ipv4_src=('10.0.0.0', '255.0.0.0'), ip_proto=6, tcp_src=80, tcp_flags=(1, 1)) actions = [ osparser.OFPExpActionSetState(state=1, table_id=0, hard_timeout=10, bit=0), osparser.OFPExpActionSetState(state=1, table_id=0, hard_timeout=10, bit=1) ] inst = [ ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=inst) datapath.send_msg(mod) # New state match = ofparser.OFPMatch(state=1, eth_type=0x0800, ipv4_src=('10.0.0.0', '255.0.0.0'), ip_proto=6, tcp_src=80, tcp_flags=(1, 0)) actions = [ osparser.OFPExpActionSetState(state=2, table_id=0, hard_timeout=10), ofparser.OFPActionOutput(2) ] inst = [ ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=inst) datapath.send_msg(mod) # Send a message with mod = osparser.OFPExpStateStatsMultipartRequest(datapath=datapath) datapath.send_msg(mod) LOG.info("DONE")
def function_lan_dmz_isolation(self, datapath): """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################################### """ Tab0 """ """ Set lookup extractor = {BiFlow} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST ], table_id=0, biflow=1) datapath.send_msg(req) """ Set lookup extractor = {BiFlow} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST ], table_id=0, biflow=1) datapath.send_msg(req) """ Tab4 """ """ Stateless """ ########################### SET GD DATA VARIABLE TAB 0 ############################################ ''' GD[0] = 0''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=0) datapath.send_msg(req) ''' GD[1] = 0 ''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=0) datapath.send_msg(req) ################################# REGOLE ############################################ match = ofparser.OFPMatch(eth_type=0x0806) actions = [ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=100, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 0 ''' # Line 0 match = ofparser.OFPMatch(state=0, in_port=DMZ_PORT, eth_type=0x0800, ipv4_dst=('10.0.0.0', '255.255.255.0')) actions = [bebaparser.OFPExpActionSetState(state=11, table_id=0)] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=0, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=100, match=match, instructions=inst) datapath.send_msg(mod) # Line 1 match = ofparser.OFPMatch(state=0, in_port=LAN_PORT, eth_type=0x0800, ipv4_dst=('8.0.0.0', '255.255.255.0')) actions = [bebaparser.OFPExpActionSetState(state=12, table_id=0)] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=0, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=99, match=match, instructions=inst) datapath.send_msg(mod) # Line 2 match = ofparser.OFPMatch(state=11, in_port=DMZ_PORT, eth_type=0x0800, ipv4_dst=('10.0.0.0', '255.255.255.0')) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=0, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=98, match=match, instructions=inst) datapath.send_msg(mod) # Line 3 match = ofparser.OFPMatch(state=11, in_port=LAN_PORT, eth_type=0x0800, ipv4_dst=('8.0.0.0', '255.255.255.0')) actions = [bebaparser.OFPExpActionSetState(state=2, table_id=0)] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=1, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=97, match=match, instructions=inst) datapath.send_msg(mod) # Line 4 match = ofparser.OFPMatch(state=12, in_port=LAN_PORT, eth_type=0x0800, ipv4_dst=('8.0.0.0', '255.255.255.0')) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=0, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=96, match=match, instructions=inst) datapath.send_msg(mod) # Line 5 match = ofparser.OFPMatch(state=12, in_port=DMZ_PORT, eth_type=0x0800, ipv4_dst=('10.0.0.0', '255.255.255.0')) actions = [bebaparser.OFPExpActionSetState(state=2, table_id=0)] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=1, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=95, match=match, instructions=inst) datapath.send_msg(mod) # Line 6 match = ofparser.OFPMatch(state=2) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionWriteMetadata(metadata=1, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=94, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 1 ''' # NOT USED IN THIS USE CASE ''' ####################### TAB 2 restore''' # NOT USED IN THIS USE CASE ''' ####################### TAB 3 translate ''' # NOT USED IN THIS USE CASE ''' ####################### TAB 4 forward ''' # Line 0 match = ofparser.OFPMatch(in_port=DMZ_PORT, metadata=(0, 0x00000000F), eth_type=0x0800, ipv4_dst=('10.0.0.0', '255.255.255.0')) actions = [] self.add_flow(datapath=datapath, table_id=4, priority=100, match=match, actions=actions) # Line 1 match = ofparser.OFPMatch(in_port=DMZ_PORT, metadata=(1, 0x00000000F), eth_type=0x0800, ipv4_dst='10.0.0.2') actions = [ ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:03"), ofparser.OFPActionOutput(LAN_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=99, match=match, actions=actions) # Line 1 BIS match = ofparser.OFPMatch(in_port=DMZ_PORT, metadata=(1, 0x00000000F), eth_type=0x0800, ipv4_dst='10.0.0.3') actions = [ ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:04"), ofparser.OFPActionOutput(LAN_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=99, match=match, actions=actions) # Line 2 match = ofparser.OFPMatch(eth_type=0x0800, ipv4_dst='8.0.0.2') actions = [ ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:02"), ofparser.OFPActionOutput(DMZ_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=98, match=match, actions=actions) # Line 3 match = ofparser.OFPMatch(eth_type=0x0800, ipv4_dst='10.0.0.2') actions = [ ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:03"), ofparser.OFPActionOutput(LAN_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=97, match=match, actions=actions) # Line 3 BIS match = ofparser.OFPMatch(eth_type=0x0800, ipv4_dst='10.0.0.3') actions = [ ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:04"), ofparser.OFPActionOutput(LAN_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=97, match=match, actions=actions)
def switch_features_handler(self, event): """ Switch sent his features, check if BEBA is supported. """ # Parse the datapath and remmber it as class variable msg = event.msg self.datapath = msg.datapath ######################################################################## ## Remove all entries from table 0,1 and 2 self.clear_table(self.datapath, 0) self.clear_table(self.datapath, 1) ######################################################################## ## Table 0 (main table) LOG.info("Configuring switch %d..." % self.datapath.id) LOG.info("Setting up Table 0 ...") # Set table 0 as stateful req = osparser.OFPExpMsgConfigureStatefulTable(datapath=self.datapath, table_id=0, stateful=1) self.datapath.send_msg(req) # Set lookup extractor = {ip_src, ip_dst, tcp_src, tcp_dst} TODO - proto=TCP?? req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_TCP_SRC, ofp.OXM_OF_TCP_DST ], table_id=0) self.datapath.send_msg(req) # Set update extractor = {ip_src, ip_dst, tcp_src, tcp_dst} req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_TCP_SRC, ofp.OXM_OF_TCP_DST ], table_id=0, bit=0) self.datapath.send_msg(req) req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_IPV4_SRC, ofp.OXM_OF_TCP_DST, ofp.OXM_OF_TCP_SRC ], table_id=0, bit=1) self.datapath.send_msg(req) LOG.info("Done.") ######################################################################## ## Table 1 (new TCP connection counter table) LOG.info("Setting up Table 1 ...") # Set table 1 as stateful req = osparser.OFPExpMsgConfigureStatefulTable(datapath=self.datapath, table_id=1, stateful=1) self.datapath.send_msg(req) # Set lookup extractor = {ip_dst,tcp_dst} # use dst IP + dst Port??? req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_TCP_DST], table_id=1) self.datapath.send_msg(req) # Set update extractor = {ip_dst,tcp_dst} req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_TCP_DST], table_id=1) self.datapath.send_msg(req) req = osparser.OFPExpMsgKeyExtract( datapath=self.datapath, command=osp.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofp.OXM_OF_IPV4_DST, ofp.OXM_OF_TCP_DST], table_id=1, bit=1) self.datapath.send_msg(req) LOG.info("Done.") ################################################################################################### ## Set switches behavior - start default behavior and afterthat start the monitoring thread ## Enable "ping" command self.load_arp_icmp() ## Load FSM (table0) for normal mode of operation self.normal_FSM.load_fsm(self.datapath) #self.ddos_mtg_FSM.load_fsm(self.datapath) ## Load SYN counter (table1) self.counter_engine.load_fsm(self.datapath) ## Create a monitoring thread (each X seconds starst the statististics collection) self.monitor_thread = hub.spawn(self._monitor) LOG.info("Starting DDoS detection ...")
def function_dynamic_nat(self, datapath): """ Set table 1 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=1, stateful=1) datapath.send_msg(req) """ Set table 2 restore """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=2, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################################### """ Tab1 """ """ Set lookup extractor = {OXM_OF_METADATA} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_METADATA], table_id=1) datapath.send_msg(req) """ Set update extractor = {OXM_OF_METADATA} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_METADATA], table_id=1) datapath.send_msg(req) """ Tab2 """ """ Set lookup extractor = {OXM_OF_IPV4_SRC, OXM_OF_IP_PROTO, OXM_OF_TCP_SRC} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IP_PROTO, ofproto.OXM_OF_TCP_SRC ], table_id=2) datapath.send_msg(req) """ Set lookup extractor = {OXM_OF_IPV4_DST, OXM_OF_IP_PROTO, OXM_OF_TCP_DST} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_IP_PROTO, ofproto.OXM_OF_TCP_DST ], table_id=2) datapath.send_msg(req) """ Tab3 """ ########################### SET STATE TABLE 1 ############################################ for stateVal in range(1, 21): state = bebaparser.OFPExpMsgSetFlowState( datapath=datapath, state=2000 + stateVal, keys=[stateVal, 0, 0, 0, 0, 0, 0, 0], table_id=1) datapath.send_msg(state) ########################### SET HF DATA VARIABLE TAB 1 ############################################ ''' GD[0] = state_label''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=1, global_data_variable_id=0, value=0) datapath.send_msg(req) ''' HF[0] = OXM_EXP_STATE [state_label] ''' req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=1, extractor_id=0, field=bebaproto.OXM_EXP_STATE) datapath.send_msg(req) ########################### SET HF DATA VARIABLE TAB 2 ############################################ ''' HF[0] = OXM_OF_IPV4_SRC [id_pkt] ''' req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=0, field=ofproto.OXM_OF_IPV4_SRC) datapath.send_msg(req) ''' HF[1] = OXM_OF_TCP_SRC [id_pkt] ''' req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=1, field=ofproto.OXM_OF_TCP_SRC) datapath.send_msg(req) ########################### SET HF DATA VARIABLE TAB 3 ############################################ ''' HF[0] = OXM_OF_METADATA [metadata] ''' req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=0, field=ofproto.OXM_OF_METADATA) datapath.send_msg(req) ################################# REGOLE ############################################ ''' ####################### TAB 0 ''' match = ofparser.OFPMatch(state=0, in_port=LAN_PORT) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=0), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=1, operand_1_gd_id=1, operand_2_cost=1), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=1, dst_field=ofproto.OXM_OF_METADATA) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=89, match=match, instructions=inst) datapath.send_msg(mod) # Line 12 match = ofparser.OFPMatch(state=1, in_port=LAN_PORT) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=88, match=match, instructions=inst) datapath.send_msg(mod) # Line 13 match = ofparser.OFPMatch(state=0, in_port=INTERNET_PORT, eth_type=0x0800, ipv4_dst='1.0.0.1') actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=87, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 1 ''' # Line 0 # HF[0] = state_label # GD[0] = state_label + 0 => GD[0] + HF[0] # state_label -> metadata => GD[0] = HF[0] match = ofparser.OFPMatch(in_port=3) actions = [ bebaparser.OFPExpActionSetDataVariable(table_id=1, opcode=bebaproto.OPCODE_SUM, output_gd_id=0, operand_1_hf_id=0, operand_2_cost=0), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_METADATA) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=100, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 2 restore''' # Line 0 # ip.src -> R0 => HF[0] -> FD[0] => FD[0] = HF[0] + 0 # tcp.src -> R1 => HF[1] -> FD[1] => FD[1] = HF[1] + 0 match = ofparser.OFPMatch(state=0, in_port=LAN_PORT) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=2), bebaparser.OFPExpActionSetDataVariable(table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=0, operand_2_cost=0), bebaparser.OFPExpActionSetDataVariable(table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=100, match=match, instructions=inst) datapath.send_msg(mod) # Line 1 # ip.dst = R0 => IPV4_DST = FD[0] # tcp.dst = R1 => TCP_DST = FD[1] match = ofparser.OFPMatch(state=1, in_port=INTERNET_PORT) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=2), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_IPV4_DST), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR, src_id=1, dst_field=ofproto.OXM_OF_TCP_DST) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=99, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 3 translate ''' # Line 3 # metadata(b16,b31) -> R1 => metadata(b16,b31) -> FD[1] => FD[1] = HF[0] # ip.src = 10.0.0.1 # tcp.src = R1 => TCP_SRC = FD[1] match = ofparser.OFPMatch(state=0, in_port=LAN_PORT, eth_type=0x0800) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=3), bebaparser.OFPExpActionSetDataVariable(table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_hf_id=0, operand_2_cost=0), ofparser.OFPActionSetField(ipv4_src="1.0.0.1"), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR, src_id=1, dst_field=ofproto.OXM_OF_TCP_SRC) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=97, match=match, instructions=inst) datapath.send_msg(mod) # Line 4 # ip.src = 10.0.0.1 # tcp.src = R1 => TCP_SRC = FD[1] match = ofparser.OFPMatch(state=1, in_port=LAN_PORT, eth_type=0x0800) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=3), ofparser.OFPActionSetField(ipv4_src='1.0.0.1'), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR, src_id=1, dst_field=ofproto.OXM_OF_TCP_SRC) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=96, match=match, instructions=inst) datapath.send_msg(mod)
def install_transport_bad(self, datapath): """ Set table 0 as stateful solo per usare GD, fa le somme del percorso """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Ci sta una table NULLA per i bug di OpenFLow con le Label MPLS """ """ Set table 2 as stateful, verifica le condizioni sul percorso <=""" req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=2, stateful=1) datapath.send_msg(req) """ Set table 3 as stateful """ req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=3, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################ """ Tab0 """ """ Non mi interessa """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Non mi interessa """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Tab2 """ """ Set lookup extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=2) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=2) datapath.send_msg(req) """ Tab3 """ """ Set lookup extractor = {MAC_DST} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_DST], table_id=3) datapath.send_msg(req) """ Set update extractor = {MAC_SRC} """ req = osparser.OFPExpMsgKeyExtract( datapath=datapath, command=osproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=3) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 0 ############################################ ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ''' GD[0] = 0 ''' req = osparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=0) datapath.send_msg(req) ########################### SET HF GD DATA VARIABLE TAB 2 ############################################ ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] ''' req = osparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=1, field=ofproto.OXM_OF_MPLS_TC) datapath.send_msg(req) ########################### SET CONDITION TAB 2 ############################################ # condition 3: MPLS_TC <= COSTO MEMORIZZATO (FD[0]) ? # condition 3: HF[1] <= FD[0] ? req = osparser.OFPExpMsgSetCondition(datapath=datapath, table_id=2, condition_id=0, condition=osproto.CONDITION_LTE, operand_1_hf_id=1, operand_2_fd_id=0) datapath.send_msg(req) '''####################### TAB 0 ''' ''' somma il costo del link di ingresso al valore memorizzato nel pacchetto mpls_tc + 1 ''' """ Riga 1 """ # GD[0] = HF[1] + 1 -> MPLS_TC + 1 # HF [1] = GD[0] -> MPLS_TC = GD[0] # GOTO Tab 2 match = ofparser.OFPMatch(eth_type=0x8847) actions = [ osparser.OFPExpActionSetDataVariable(table_id=0, opcode=osproto.OPCODE_SUM, output_gd_id=0, operand_1_hf_id=1, operand_2_cost=2), osparser.OFPExpActionWriteContextToField( src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_MPLS_TC) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=1198, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 1 NULLA serve solo per i bug di OpenFlow, servono 2 stage xke le modifiche MPLS siano visibili''' # Non fa niente, ci sta solo per risolvere bug (presunti) di OpenFlow match = ofparser.OFPMatch(eth_type=0x8847) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=0, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 2 ''' ''' C[0] verifica se il costo memorizzato nel pacchetto e' <= di quello gia conosciuto (in pratica se il pacchetto ha fatto un percorso migliore) ''' """ Riga 1 """ # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0] # MetaData: 1 -> Pacchetto duplicato # azione DROP match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0) actions = [osparser.OFPExpActionSetState(state=1, table_id=2)] self.add_flow(datapath=datapath, table_id=2, priority=198, match=match, actions=actions) """ Riga 2 """ # C[0]: MPLS_TC <= COSTO MEMORIZZATO -> HF[1] <= FD[0] # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC # SetState(1) # azione GOTO Tab 3 match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=1) actions = [ osparser.OFPExpActionSetState(state=1, table_id=2), osparser.OFPExpActionSetDataVariable(table_id=2, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=98, match=match, instructions=inst) datapath.send_msg(mod) """ Riga 3 """ # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC # SetState(1) # azione GOTO Tab 3 match = ofparser.OFPMatch(state=0, eth_type=0x8847) actions = [ osparser.OFPExpActionSetState(state=1, table_id=2), osparser.OFPExpActionSetDataVariable(table_id=2, opcode=osproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=8, match=match, instructions=inst) datapath.send_msg(mod) '''# ####################### TAB 3 semplicemente MAC Learning ''' # for each input port, for each state for i in range(1, N + 1): for s in range(N + 1): match = ofparser.OFPMatch(in_port=i, state=s) if s == 0: out_port = ofproto.OFPP_FLOOD else: out_port = s # actions = [osparser.OFPExpActionSetState(state=i, table_id=3, hard_timeout=10), actions = [ osparser.OFPExpActionSetState(state=i, table_id=3), ofparser.OFPActionOutput(out_port) ] self.add_flow(datapath=datapath, table_id=3, priority=0, match=match, actions=actions)
def switch_features_handler(self, event): """ Switch sent his features, check if Beba supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=0) datapath.send_msg(req) ########################################################################################### """ Set GDV[1]=0 """ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=1, value=0) datapath.send_msg(req) """ Set GDV[2]=2 """ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=2, value=2) datapath.send_msg(req) """ Set GDV[3]=5 """ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=3, value=5) datapath.send_msg(req) """ Update function: FDV[2] = GDV[2]*10 + 1*4 + GDV[1]*5 - GDV[3]*6 = 2*30 + 1*4 + 0*5 - 5*6 = 34 """ match = ofparser.OFPMatch() actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_POLY_SUM, output_fd_id=2, operand_1_gd_id=2, operand_2_cost=1, operand_3_gd_id=1, operand_4_gd_id=3, coeff_1=30, coeff_2=4, coeff_3=5, coeff_4=-6), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD) ] self.add_flow(datapath=datapath, table_id=0, priority=0, match=match, actions=actions) """
def function_load_balancer(self, datapath): """ Tab0 """ """ Set lookup extractor = {BiFlow} """ # GIA CONFIGURATA """ Set table 3 translate """ req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=3, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################################### """ Tab3 """ """ Set lookup extractor = {OXM_OF_IPV4_SRC, OXM_OF_TCP_SRC} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_TCP_SRC], table_id=3) datapath.send_msg(req) """ Set update extractor = {OXM_OF_IPV4_SRC, OXM_OF_TCP_SRC} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_TCP_SRC], table_id=3) datapath.send_msg(req) ########################### SET GD E HF DATA VARIABLE TAB 3 ############################################ ''' GD[0] = 0''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=0, value=0) datapath.send_msg(req) ''' GD[1] = LAN_DUE 10.0.0.2 hexadecimal''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=1, value=0x0200000a) datapath.send_msg(req) ''' GD[2] = LAN_TRE 10.0.0.3 hexadecimal''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=2, value=0x0300000a) datapath.send_msg(req) ''' GD[3] = PORT 80 ''' req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=3, global_data_variable_id=3, value=0x5000) datapath.send_msg(req) ################################# RULES ############################################ ''' ####################### TAB 0 ''' # Line 7 match = ofparser.OFPMatch(state=0, in_port=INTERNET_PORT, eth_type=0x0800, ipv4_dst='1.0.0.1', ip_proto=6, tcp_dst=80) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=0), bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=0, operand_1_gd_id=0, operand_2_cost=1), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_METADATA) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=93, match=match, instructions=inst) datapath.send_msg(mod) # Line 8 match = ofparser.OFPMatch(state=1, in_port=INTERNET_PORT, eth_type=0x0800, ipv4_dst='1.0.0.1', ip_proto=6, tcp_dst=80) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=92, match=match, instructions=inst) datapath.send_msg(mod) # Line 9 match = ofparser.OFPMatch(state=0, in_port=LAN_PORT, eth_type=0x0800, ipv4_src='10.0.0.2', ip_proto=6, tcp_src=80) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=91, match=match, instructions=inst) datapath.send_msg(mod) # Line 10 match = ofparser.OFPMatch(state=0, in_port=LAN_PORT, eth_type=0x0800, ipv4_src='10.0.0.3', ip_proto=6, tcp_src=80) actions = [] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=90, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 3 translate ''' # Line 0 # ip.dst = 10.0.0.2 # tcp.dst = 80 # 10.0.0.2 -> R0 => 10.0.0.2 -> FD[0] => FD[0] = GD[0] + 10.0.0.2 => 0 + 10.0.0.2 # 80 -> R1 => 80 -> FD[1] => GD[0] + 80 => 0 + 80 match = ofparser.OFPMatch(state=0, in_port=INTERNET_PORT, metadata=(0, 0x000000001), eth_type=0x0800, ip_proto=6) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=3), ofparser.OFPActionSetField(ipv4_dst='10.0.0.2'), ofparser.OFPActionSetField(tcp_dst=80), # tolto per test bebaparser.OFPExpActionSetDataVariable(table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_gd_id=1, operand_2_cost=0), bebaparser.OFPExpActionSetDataVariable(table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_gd_id=0, operand_2_cost=80) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=100, match=match, instructions=inst) datapath.send_msg(mod) # Line 1 # ip.dst = 10.0.0.3 # tcp.dst = 80 # 10.0.0.3 -> R0 => 10.0.0.3 -> FD[0] => FD[0] = GD[0] + 10.0.0.3 => 0 + 10.0.0.3 # 80 -> R1 => 80 -> FD[1] => GD[0] + 80 => 0 + 80 match = ofparser.OFPMatch(state=0, in_port=INTERNET_PORT, metadata=(1, 0x000000001), eth_type=0x0800, ip_proto=6) actions = [ bebaparser.OFPExpActionSetState(state=1, table_id=3), ofparser.OFPActionSetField(ipv4_dst='10.0.0.3'), ofparser.OFPActionSetField(tcp_dst=80), # tolto per test bebaparser.OFPExpActionSetDataVariable(table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_gd_id=2, operand_2_cost=0), bebaparser.OFPExpActionSetDataVariable(table_id=3, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_gd_id=0, operand_2_cost=80) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=99, match=match, instructions=inst) datapath.send_msg(mod) # Line 2 # ip.dst = R0 => IPV4_DST = FD[0] # tcp.dst = R1 => TCP_DST = FD[1] match = ofparser.OFPMatch(state=1, in_port=INTERNET_PORT) actions = [ bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR, src_id=0, dst_field=ofproto.OXM_OF_IPV4_DST), bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR, src_id=1, dst_field=ofproto.OXM_OF_TCP_DST) ] inst = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(4) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=3, priority=98, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 4 forward ''' # Line 4 match = ofparser.OFPMatch(in_port=LAN_PORT, eth_type=0x0800, ipv4_src='10.0.0.2', ip_proto=6, tcp_src=80) actions = [ ofparser.OFPActionSetField(ipv4_src='1.0.0.1'), ofparser.OFPActionSetField(tcp_src=80), ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:01"), ofparser.OFPActionOutput(INTERNET_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=96, match=match, actions=actions) # Line 5 match = ofparser.OFPMatch(in_port=LAN_PORT, eth_type=0x0800, ipv4_src='10.0.0.3', ip_proto=6, tcp_src=80) actions = [ ofparser.OFPActionSetField(ipv4_src='1.0.0.1'), ofparser.OFPActionSetField(tcp_src=80), ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:01"), ofparser.OFPActionOutput(INTERNET_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=95, match=match, actions=actions) # Line 6 match = ofparser.OFPMatch() actions = [ ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:01"), ofparser.OFPActionOutput(INTERNET_PORT) ] self.add_flow(datapath=datapath, table_id=4, priority=94, match=match, actions=actions)
def install_spines(self, datapath): ######################### TABLE 1 CONFIG ############### req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) # mpls extractor req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) # timestamp extractor req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) # packet length extractor req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=2, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=0, table_id=0, operand_1_hf_id=1, operand_2_fd_id=4) datapath.send_msg(req) ########################### TABLE 1: MEASURING ##################### for i in LEAVES: if i == 1: out_ports = [2, 3] elif i == 2: out_ports = [1, 3] elif i == 3: out_ports = [1, 2] buckets = [] actions = [ bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=4, dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput(out_ports[0]) ] buckets.append(ofparser.OFPBucket(actions=actions)) actions = [ bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=5, dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput(out_ports[1]) ] buckets.append(ofparser.OFPBucket(actions=actions)) # send the group action req = ofparser.OFPGroupMod(datapath=datapath, type_=ofproto.OFPGT_ALL, group_id=i, buckets=buckets) datapath.send_msg(req) match = ofparser.OFPMatch(in_port=i, eth_type=0x8847) actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=4, operand_1_hf_id=0, operand_2_gd_id=out_ports[0]), bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=5, operand_1_hf_id=0, operand_2_gd_id=out_ports[1]), ofparser.OFPActionGroup(i) ] self.add_flow(datapath=datapath, priority=600, table_id=0, match=match, actions=actions) # first packet of a flow match = ofparser.OFPMatch(state=0, in_port=i) actions = [ bebaparser.OFPExpActionSetState(table_id=0, state=1, idle_timeout=2), # saves timestamp bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_hf_id=1, operand_2_cost=PROBE_FREQ) ] insts = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=500, match=match, instructions=insts) datapath.send_msg(mod) # simple forwarding packets go to second table to forward match = ofparser.OFPMatch(state=1, in_port=i, condition0=1) actions = [ # calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=1, operand_1_hf_id=1, operand_2_fd_id=0), # calculates rate: R = (bytes / deltaT_ms) * 8 [kb/s] bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_MUL, output_fd_id=2, operand_1_fd_id=2, operand_2_cost=8), # stores the result in FDV[3]: THE FLOW ESTIMATED RATE bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_DIV, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=1), # calculates ewma bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_EWMA, output_fd_id=3, operand_1_fd_id=3, operand_2_cost=ALPHA, operand_3_fd_id=2), # saves current timestamp bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), # saves timestamp + probe freq bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_hf_id=1, operand_2_cost=PROBE_FREQ), # reset byte counter bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUB, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=2), # saves in GDV[i] the ewma bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=i, operand_1_fd_id=3, operand_2_cost=0) ] instructions = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, priority=0, table_id=0, match=match, instructions=instructions) datapath.send_msg(mod) match = ofparser.OFPMatch(state=1, in_port=i, condition0=0) actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_fd_id=2, operand_2_hf_id=2) ] instructions = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), ofparser.OFPInstructionGotoTable(1) ] mod = ofparser.OFPFlowMod(datapath=datapath, priority=0, table_id=0, match=match, instructions=instructions) datapath.send_msg(mod) ######################## TABLE 2: FORWARDING ################ for i in LEAVES: match = ofparser.OFPMatch(eth_dst=MAC_ADDRS[i - 1]) actions = [ofparser.OFPActionOutput(i)] self.add_flow(datapath=datapath, table_id=1, priority=0, match=match, actions=actions)
def switch_features_handler(self, event): """ Switche sent his features, check if OpenState supported """ msg = event.msg datapath = msg.datapath LOG.info("Configuring switch %d..." % datapath.id) """ Set table 0 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable( datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set table 1 as stateful """ req = bebaparser.OFPExpMsgConfigureStatefulTable( datapath=datapath, table_id=1, stateful=1) datapath.send_msg(req) ############################### LOOKUP/UPDATE ################ """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST], table_id=0, biflow=1) datapath.send_msg(req) """ Set update extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST], table_id=0, biflow=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=1) datapath.send_msg(req) """ Set update extractor = {eth_src} """ req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_ETH_SRC], table_id=1) datapath.send_msg(req) ########################### SET GD DATA VARIABLE ############################################ # req = bebaparser.OFPExpMsgHeaderFieldExtract( # datapath=datapath, # table_id=0, # extractor_id=0, # field=ofproto.OXM_OF_IPV4_SRC # ) # datapath.send_msg(req) req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=313 ) datapath.send_msg(req) req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=2, value=22 ) datapath.send_msg(req) req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=4, value=44 ) datapath.send_msg(req) req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=5, value=55 ) datapath.send_msg(req) ########################### SET GD DATA VARIABLE ############################################ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=1, global_data_variable_id=3, value=55 ) datapath.send_msg(req) ########################### SET HF DATA VARIABLE TAB 1 ############################################ # SI PUO FARE??? ''' HF[0] = OXM_OF_METADATA [id_pkt] ''' req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=1, extractor_id=0, field=ofproto.OXM_OF_ETH_SRC ) datapath.send_msg(req) # ''' HF[0] = OXM_OF_METADATA [id_pkt] ''' # req = bebaparser.OFPExpMsgHeaderFieldExtract( # datapath=datapath, # table_id=1, # extractor_id=0, # field=bebaproto.OXM_EXP_STATE # ) # datapath.send_msg(req) # aggiunta cosi tanto per fare un nuovo commit # ''' HF[0] = OXM_OF_METADATA [id_pkt] ''' # req = bebaparser.OFPExpMsgHeaderFieldExtract( # datapath=datapath, # table_id=1, # extractor_id=0, # field=bebaproto.OXM_EXP_STATE # ) # datapath.send_msg(req) ''' ####################### TAB 0 NULLA serve solo per i bug di OpenFlow, servono 2 stage xke le modifiche MPLS siano visibili''' # Non fa niente, ci sta solo per risolvere bug (presunti) di OpenFlow # match = ofparser.OFPMatch(condition0=0) # actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0), # ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] # inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)] # mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, # priority=0, match=match, instructions=inst) # datapath.send_msg(mod) # match = ofparser.OFPMatch()#condition0=1) # actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0), # bebaparser.OFPExpActionSetDataVariable(table_id=0, port_id=1, opcode=bebaproto.OPCODE_SUM, output_mem_pd_id=0, operand_1_mem_pd_id=1, operand_2_mem_pd_id=1), # # bebaparser.OFPExpActionWriteContextToField(src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,src_id=0,dst_field=ofproto.OXM_OF_MPLS_LABEL), # bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=3, operand_1_hf_id=0, operand_2_cost=0), # ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] # inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)] # mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, # priority=0, match=match, instructions=inst) # datapath.send_msg(mod) # match = ofparser.OFPMatch(eth_type=0x0800 ,ipv4_src=('10.0.0.0','255.255.255.0')) match = ofparser.OFPMatch() actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0), # bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_hf_id=0, operand_2_cost=3)] # bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_gd_id=0, operand_2_gd_id=2)] bebaparser.OFPExpActionWriteContextToField(src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,src_id=0,dst_field=ofproto.OXM_OF_METADATA)] inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), # ofparser.OFPInstructionWriteMetadata(metadata=13, metadata_mask=0xFFFFFFFF), ofparser.OFPInstructionGotoTable(1)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=inst) datapath.send_msg(mod) ''' ####################### TAB 1 ''' match = ofparser.OFPMatch()#state=2) actions = [bebaparser.OFPExpActionSetState(state=2, table_id=1), bebaparser.OFPExpActionSetDataVariable(table_id=1, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_hf_id=0, operand_2_cost=1), ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)] # bebaparser.OFPExpActionSetDataVariable(table_id=1, opcode=bebaproto.OPCODE_SUM, output_gd_id=0, operand_1_gd_id=1, operand_2_cost=3)] inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=10, match=match, instructions=inst) datapath.send_msg(mod) # match = ofparser.OFPMatch(metadata=313) # actions = [bebaparser.OFPExpActionSetState(state=2, table_id=1), # bebaparser.OFPExpActionSetDataVariable(table_id=1, opcode=bebaproto.OPCODE_SUM, output_gd_id=0, operand_1_gd_id=3, operand_2_cost=3)] # inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)] # mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, # priority=0, match=match, instructions=inst) # datapath.send_msg(mod) # # for each input port, for each state # for i in range(1, N+1): # for s in range(N+1): # match = ofparser.OFPMatch(in_port=i, state=s) # if s == 0: # out_port = ofproto.OFPP_FLOOD # else: # out_port = s # actions = [bebaparser.OFPExpActionSetState(state=i, table_id=0, hard_timeout=10), # ofparser.OFPActionOutput(out_port)] # self.add_flow(datapath=datapath, table_id=0, priority=0, # match=match, actions=actions) """ Need to drop some packets for DEMO puporses only (avoid learning before manual send_eth)"""
def install_leaves(self, datapath): # Send probe packet to packet generation table req = bebaparser.OFPExpMsgAddPktTmp(datapath=datapath, pkttmp_id=0, pkt_data=pkt_raw) datapath.send_msg(req) ##################################### TABLE 0: DISPATCHING ################################################## ######################### TABLE 0 CONFIG ############### req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=0, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) """ Set update extractor = {eth_dst} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=0) datapath.send_msg(req) """ Field extractor for mpls label """ req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) """ Field extractor for timestamp """ req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=0, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) """ Packet counter_max for designing probe frequency """ req = bebaparser.OFPExpMsgsSetGlobalDataVariable( datapath=datapath, table_id=0, global_data_variable_id=0, value=PROBE_FREQ) datapath.send_msg(req) """ Condition C0: if counter reaches counter_max, then trigger probe sending """ req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, table_id=0, condition_id=0, condition=bebaproto.CONDITION_GTE, operand_1_fd_id=0, operand_2_gd_id=0) datapath.send_msg(req) req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, table_id=0, condition_id=3, condition=bebaproto.CONDITION_GTE, operand_1_fd_id=0, operand_2_gd_id=0) datapath.send_msg(req) ##################################### TABLE 0 FLOWS ################################################## """ RECEIVE PROBE ACTION """ """ When a probe is received tab0 sends it to tab3""" """ match: MPLS """ """ no action """ """ instruction: goto tab3""" match = ofparser.OFPMatch(eth_type=0x8847) instructions = [ofparser.OFPInstructionGotoTable(3)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=200, match=match, instructions=instructions) datapath.send_msg(mod) """ For packets from down ports (attached to hosts): go to ToR Discovery table (1) """ for i in DOWN_PORTS: match = ofparser.OFPMatch(in_port=i) instructions = [ofparser.OFPInstructionGotoTable(1)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=10, match=match, instructions=instructions) datapath.send_msg(mod) match = ofparser.OFPMatch() instructions = [ofparser.OFPInstructionGotoTable(2)] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0, priority=0, match=match, instructions=instructions) datapath.send_msg(mod) # using low bitrate flows to refresh the estimates. For testing purposes only for i in [0, 1]: match = ofparser.OFPMatch(in_port=3, eth_type=0x0800, ip_proto=6, tcp_dst=10000 + i) actions = [ofparser.OFPActionOutput(i + 1)] self.add_flow(datapath=datapath, table_id=0, priority=200, match=match, actions=actions) match = ofparser.OFPMatch(in_port=3, eth_type=0x0800, ip_proto=6, tcp_src=10000 + i) actions = [ofparser.OFPActionOutput(i + 1)] self.add_flow(datapath=datapath, table_id=0, priority=200, match=match, actions=actions) ######################## TABLE 1 ToR DISCOVERY ######################################################### # this cycle writes metadata specifying to which leaf belongs the packet for i in LEAVES: if i != datapath.id: match = ofparser.OFPMatch(eth_dst=MAC_ADDRS[i - 1]) instructions = [ ofparser.OFPInstructionWriteMetadata( metadata=i, metadata_mask=0xffffffff), ofparser.OFPInstructionGotoTable(3) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1, priority=0, match=match, instructions=instructions) datapath.send_msg(mod) ######################### TABLE 2: ACTIVE PROBING ###################################################### ################### TABLE 2 CONFIG ######### req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=2, stateful=1) datapath.send_msg(req) """ Set lookup extractor = {IN_PORT} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=2) datapath.send_msg(req) """ Set update extractor = {IN_PORT} """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ofproto.OXM_OF_IN_PORT], table_id=2) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=2, extractor_id=2, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_GTE, condition_id=0, table_id=2, operand_1_hf_id=1, operand_2_fd_id=4) datapath.send_msg(req) ############################### TABLE 2 FLOWS ############################# match = ofparser.OFPMatch(state=0) actions = [ bebaparser.OFPExpActionSetState(table_id=2, state=1, idle_timeout=2), # saves timestamp bebaparser.OFPExpActionSetDataVariable(table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_hf_id=1, operand_2_cost=PROBE_FREQ), ofparser.OFPActionOutput(3) ] self.add_flow(datapath=datapath, table_id=2, priority=500, match=match, actions=actions) """ For every packet coming from spine ports, calculates ewma """ for i in UPPER_PORTS: # simply ewma measuring match = ofparser.OFPMatch(state=1, in_port=i, condition0=1) actions_ewma_1 = [ # calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUB, output_fd_id=1, operand_1_hf_id=1, operand_2_fd_id=0), # calculates rate: R = (bytes / deltaT_ms) * 8 [kb/s] bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_MUL, output_fd_id=2, operand_1_fd_id=2, operand_2_cost=8), # stores the result in FDV[3]: THE FLOW ESTIMATED RATE bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_DIV, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=1), # calculates ewma bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_EWMA, output_fd_id=3, operand_1_fd_id=3, operand_2_cost=ALPHA, operand_3_fd_id=2), # saves current timestamp bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=0, operand_1_hf_id=1, operand_2_cost=0), # saves timestamp + probe freq bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=4, operand_1_hf_id=1, operand_2_cost=PROBE_FREQ), # reset byte counter bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUB, output_fd_id=2, operand_1_fd_id=2, operand_2_fd_id=2), # saves in GDV[i] the ewma bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_gd_id=i, operand_1_fd_id=3, operand_2_cost=0) ] # actions for the packet actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)] # action group for the probes probe_actions1 = [ ofparser.OFPActionSetField(mpls_tc=datapath.id), # the GDV[i] bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=i, dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput(i) ] probe_actions2 = [ ofparser.OFPActionSetField( mpls_tc=datapath.id), # the GDV[other] bebaparser.OFPExpActionWriteContextToField( src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR, src_id=(1 if i == 2 else 2), dst_field=ofproto.OXM_OF_MPLS_LABEL), ofparser.OFPActionOutput((1 if i == 2 else 2)) ] # apply packet actions insts = [ ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), # apply packet generation bebaparser.OFPInstructionInSwitchPktGen( pkttmp_id=0, actions=probe_actions1), bebaparser.OFPInstructionInSwitchPktGen(pkttmp_id=0, actions=probe_actions2) ] mod = ofparser.OFPFlowMod(datapath=datapath, table_id=2, priority=30, match=match, instructions=insts) datapath.send_msg(mod) match = ofparser.OFPMatch(state=1, in_port=i, condition0=0) actions_ewma_2 = [ bebaparser.OFPExpActionSetDataVariable( table_id=2, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_fd_id=2, operand_2_hf_id=2) ] self.add_flow(datapath=datapath, table_id=2, priority=30, match=match, actions=actions_ewma_2 + [ofparser.OFPActionOutput(3)]) # using low bitrate flows to refresh the estimates. For testing purposes only for j in [0, 1]: match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_dst=10000 + j, condition0=1) actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_src=10000 + j, condition0=1) actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_dst=10000 + j, condition0=0) actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) match = ofparser.OFPMatch(in_port=i, eth_type=0x0800, ip_proto=6, tcp_src=10000 + j, condition0=0) actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)] self.add_flow(datapath=datapath, table_id=2, priority=150, match=match, actions=actions) ######################## TABLE 3: FORWARDING ############################################################## ######################## TABLE 3 CONFIG ##################################################################### ##### GDV[1] contains path utilization to dest 1 on port 1 ##### GDV[2] contains path utilization to dest 2 on port 1 ##### GDV[3] contains path utilization to dest 1 on port 2 ##### GDV[4] contains path utilization to dest 2 on port 2 req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath, table_id=3, stateful=1) datapath.send_msg(req) """ Set lookup extractor """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST ], table_id=3) datapath.send_msg(req) """ Set update extractor """ req = bebaparser.OFPExpMsgKeyExtract( datapath=datapath, command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR, fields=[ ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST ], table_id=3) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=0, field=ofproto.OXM_OF_MPLS_LABEL) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=1, field=bebaproto.OXM_EXP_TIMESTAMP) datapath.send_msg(req) req = bebaparser.OFPExpMsgHeaderFieldExtract( datapath=datapath, table_id=3, extractor_id=2, field=bebaproto.OXM_EXP_PKT_LEN) datapath.send_msg(req) #################################### TABLE 3 FLOWS ################################### # many conditions as the number of LEAVES-1 # for i in LEAVES except datapath.id: create condition[i] # in case of 2 Spines for destLeaf in [1, 2]: # C[destLeaf]: in which port there is less utilization for that destination? req = bebaparser.OFPExpMsgSetCondition( datapath=datapath, condition=bebaproto.CONDITION_LTE, condition_id=destLeaf, table_id=3, operand_1_gd_id=destLeaf, operand_2_gd_id=destLeaf + 2) datapath.send_msg(req) # leaf number dependent flows if datapath.id == 1: # LEAF 1 new flows: fetch the destination leaf and check the appropriate condition match1true = ofparser.OFPMatch(metadata=2, condition1=1, state=0) # dst=2, port 1 match2true = ofparser.OFPMatch(metadata=3, condition2=1, state=0) # dst=3, port 1 match1false = ofparser.OFPMatch(metadata=2, condition1=0, state=0) # dst=2, port 2 match2false = ofparser.OFPMatch(metadata=3, condition2=0, state=0) # dst=3, port 2 elif datapath.id == 2: # LEAF 2 new flows: fetch the destination leaf and check the appropriate condition match1true = ofparser.OFPMatch(metadata=1, condition1=1, state=0) # dst=1, port 1 match2true = ofparser.OFPMatch(metadata=3, condition2=1, state=0) # dst=3, port 1 match1false = ofparser.OFPMatch(metadata=1, condition1=0, state=0) # dst=1, port 2 match2false = ofparser.OFPMatch(metadata=3, condition2=0, state=0) # dst=3, port 2 elif datapath.id == 3: # LEAF 3 new flows: fetch the destination leaf and check the appropriate condition match1true = ofparser.OFPMatch(metadata=1, condition1=1, state=0) # dst=1, port 1 match2true = ofparser.OFPMatch(metadata=2, condition2=1, state=0) # dst=2, port 1 match1false = ofparser.OFPMatch(metadata=1, condition1=0, state=0) # dst=1, port 2 match2false = ofparser.OFPMatch(metadata=2, condition2=0, state=0) # dst=2, port 2 # if port 1 is better, set_state(1) and output 1 actions_true = [ bebaparser.OFPExpActionSetState(state=1, table_id=3, idle_timeout=RTT), ofparser.OFPActionOutput(1) ] # if port 2 is better, set_state(2) and output 2 actions_false = [ bebaparser.OFPExpActionSetState(state=2, table_id=3, idle_timeout=RTT), ofparser.OFPActionOutput(2) ] self.add_flow(datapath=datapath, table_id=3, priority=20, match=match1true, actions=actions_true) self.add_flow(datapath=datapath, table_id=3, priority=20, match=match2true, actions=actions_true) self.add_flow(datapath=datapath, table_id=3, priority=20, match=match1false, actions=actions_false) self.add_flow(datapath=datapath, table_id=3, priority=20, match=match2false, actions=actions_false) """ extract external probes' data and store in GDVs """ match = ofparser.OFPMatch(eth_type=0x8847, mpls_tc=datapath.id) self.add_flow(datapath=datapath, table_id=3, priority=300, match=match, actions=[]) for i in UPPER_PORTS: for leafNo in LEAVES: if leafNo != datapath.id: match = ofparser.OFPMatch(in_port=i, eth_type=0x8847, mpls_tc=leafNo) """ actions: save in GDVs external probes' data """ if datapath.id == 1: if leafNo == 2: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(1 if i == 1 else 3), operand_1_hf_id=0, operand_2_cost=0) ] elif leafNo == 3: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(2 if i == 1 else 4), operand_1_hf_id=0, operand_2_cost=0) ] elif datapath.id == 2: if leafNo == 1: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(1 if i == 1 else 3), operand_1_hf_id=0, operand_2_cost=0) ] elif leafNo == 3: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(2 if i == 1 else 4), operand_1_hf_id=0, operand_2_cost=0) ] elif datapath.id == 3: if leafNo == 1: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(1 if i == 1 else 3), operand_1_hf_id=0, operand_2_cost=0) ] elif leafNo == 2: actions = [ bebaparser.OFPExpActionSetDataVariable( table_id=3, opcode=bebaproto.OPCODE_SUM, output_gd_id=(2 if i == 1 else 4), operand_1_hf_id=0, operand_2_cost=0) ] self.add_flow(datapath=datapath, table_id=3, priority=200, match=match, actions=actions) for s in UPPER_PORTS: for metadata in LEAVES: # normal conditions match = ofparser.OFPMatch(in_port=3, state=s, metadata=metadata) # , condition4=0) actions = [ofparser.OFPActionOutput(s)] self.add_flow(datapath=datapath, table_id=3, priority=30, match=match, actions=actions)