<s> import struct <EOL> from ryu . base import app_manager <EOL> from ryu . controller . handler import MAIN_DISPATCHER <EOL> from ryu . controller . handler import set_ev_cls <EOL> from ryu . ofproto import ofproto_v1_0 <EOL> from ryu . lib import addrconv <EOL> from ryu . lib import lacplib <EOL> from ryu . lib . dpid import str_to_dpid <EOL> class SimpleSwitchLacp ( app_manager . RyuApp ) : <EOL> OFP_VERSIONS = [ ofproto_v1_0 . OFP_VERSION ] <EOL> _CONTEXTS = { '<STR_LIT>' : lacplib . LacpLib } <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( SimpleSwitchLacp , self ) . __init__ ( * args , ** kwargs ) <EOL> self . mac_to_port = { } <EOL> self . _lacp = kwargs [ '<STR_LIT>' ] <EOL> self . _lacp . add ( <EOL> dpid = str_to_dpid ( '<STR_LIT>' ) , ports = [ <NUM_LIT:1> , <NUM_LIT:2> ] ) <EOL> self . _lacp . add ( <EOL> dpid = str_to_dpid ( '<STR_LIT>' ) , ports = [ <NUM_LIT:3> , <NUM_LIT:4> , <NUM_LIT:5> ] ) <EOL> self . _lacp . add ( <EOL> dpid = str_to_dpid ( '<STR_LIT>' ) , ports = [ <NUM_LIT:1> , <NUM_LIT:2> ] ) <EOL> def add_flow ( self , datapath , in_port , dst , actions ) : <EOL> ofproto = datapath . ofproto <EOL> parser = datapath . ofproto_parser <EOL> match = parser . OFPMatch ( in_port = in_port , <EOL> dl_dst = addrconv . mac . text_to_bin ( dst ) ) <EOL> mod = parser . OFPFlowMod ( <EOL> datapath = datapath , match = match , cookie = <NUM_LIT:0> , <EOL> command = ofproto . OFPFC_ADD , actions = actions ) <EOL> datapath . send_msg ( mod ) <EOL> def del_flow ( self , datapath , dst ) : <EOL> ofproto = datapath . ofproto <EOL> parser = datapath . ofproto_parser <EOL> match = parser . OFPMatch ( dl_dst = addrconv . mac . text_to_bin ( dst ) ) <EOL> mod = parser . OFPFlowMod ( <EOL> datapath = datapath , match = match , cookie = <NUM_LIT:0> , <EOL> command = ofproto . OFPFC_DELETE ) <EOL> datapath . send_msg ( mod ) <EOL> @ set_ev_cls ( lacplib . EventPacketIn , MAIN_DISPATCHER ) <EOL> def _packet_in_handler ( self , ev ) : <EOL> msg = ev . msg <EOL> datapath = msg . datapath <EOL> ofproto = datapath . ofproto <EOL> ( dst_ , src_ , _eth_type ) = struct . unpack_from ( <EOL> '<STR_LIT>' , buffer ( msg . data ) , <NUM_LIT:0> ) <EOL> src = addrconv . mac . bin_to_text ( src_ ) <EOL> dst = addrconv . mac . bin_to_text ( dst_ ) <EOL> dpid = datapath . id <EOL> self . mac_to_port . setdefault ( dpid , { } ) <EOL> self . logger . info ( "<STR_LIT>" , <EOL> dpid , src , dst , msg . in_port ) <EOL> self . mac_to_port [ dpid ] [ src ] = msg . in_port <EOL> if dst in self . mac_to_port [ dpid ] : <EOL> out_port = self . mac_to_port [ dpid ] [ dst ] <EOL> else : <EOL> out_port = ofproto . OFPP_FLOOD <EOL> actions = [ datapath . ofproto_parser . OFPActionOutput ( out_port ) ] <EOL> if out_port != ofproto . OFPP_FLOOD : <EOL> self . add_flow ( datapath , msg . in_port , dst , actions ) <EOL> out = datapath . ofproto_parser . OFPPacketOut ( <EOL> datapath = datapath , buffer_id = msg . buffer_id , in_port = msg . in_port , <EOL> actions = actions ) <EOL> datapath . send_msg ( out ) <EOL> @ set_ev_cls ( lacplib . EventSlaveStateChanged , MAIN_DISPATCHER ) <EOL> def _slave_state_changed_handler ( self , ev ) : <EOL> datapath = ev . datapath <EOL> dpid = datapath . id <EOL> port_no = ev . port <EOL> enabled = ev . enabled <EOL> self . logger . info ( "<STR_LIT>" , <EOL> port_no , enabled ) <EOL> if dpid in self . mac_to_port : <EOL> for mac in self . mac_to_port [ dpid ] : <EOL> self . del_flow ( datapath , mac ) <EOL> del self . mac_to_port [ dpid ] <EOL> self . mac_to_port . setdefault ( dpid , { } ) </s>
