La primera aproximación para filtrar por MAC utilizando un controlador SDN fue utilizando a Ryu como controlador. Mediante el siguiente script que se encuentra debajo.
En este comienzo lo que se realizo fue pasarle una dirección, como por ejemplo la “00:00:00:00:00:02” y tanto los paquetes de origen como de destinatario a esa MAC se ven descartados.
El resultado de esto, probandolo con una topologia de 5 switch y 5 host fue la siguiente:
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
class SimpleSwitch13v2(app_manager.RyuApp):
OFP_VERSIONS= [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(SimpleSwitch13v2,self).__init__(*args,**kwargs)
self.mac_to_port = {}
print (self.mac_to_port)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self,ev):
datapath = ev.msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
match = parser.OFPMatch()
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath,0,match,actions)
def add_flow(self,datapath,priority,match,actions):
ofproto=datapath.ofproto
parser = datapath.ofproto_parser
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
mod = parser.OFPFlowMod(datapath=datapath,priority=priority,match=match,instructions=inst)
datapath.send_msg(mod)
@set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_DISPATCHER)
def _packet_in_handler(self,ev):
msg= ev.msg
datapath = msg.datapath
ofproto= datapath.ofproto
parser = datapath.ofproto_parser
dpid= datapath.id
self.mac_to_port.setdefault(dpid, {})
pkt = packet.Packet(msg.data)
eth_pkt = pkt.get_protocol(ethernet.ethernet)
dst =eth_pkt.dst
src = eth_pkt.src
in_port = msg.match["in_port"]
self.mac_to_port[dpid][src]= in_port
if dst in self.mac_to_port[dpid]:
out_port = self.mac_to_port[dpid][dst]
else:
out_port = ofproto.OFPP_FLOOD
actions = [parser.OFPActionOutput(out_port)]
if src=="00:00:00:00:00:02":
actions = []
if out_port!=ofproto.OFPP_FLOOD:
match = parser.OFPMatch(in_port=in_port, eth_dst=dst,eth_src=src)
self.add_flow(datapath,1,match,actions)
out = parser.OFPPacketOut(datapath=datapath,buffer_id=ofproto.OFP_NO_BUFFER, in_port=in_port, actions=actions,data=msg.data)
datapath.send_msg(out)