Commit dcbb9afe authored by Anurag Kumar's avatar Anurag Kumar

Upload New File

parent 6e2e5cca
import json
from ryu import cfg
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_0, ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import ipv4
from ryu.lib.packet import ether_types
from ryu.lib.packet import arp
from ryu.lib.ofp_pktinfilter import packet_in_filter, RequiredTypeFilter
from .conf_mgr import BGPSpeakerManager
from fwd_util import RoutingClass
CONF = cfg.CONF
# DHCP = {'IP': '0.0.0.0',
# 'MAC': 'c0:ff:ee:c0:ff:ee'}
# DHCP_IP = '0.0.0.0'
# DHCP_MAC = 'c0:ff:ee:c0:ff:ee'
# integrate with DragonKnight CLI
# dragon_knight_flag = False
# try:
# from dragon_knight import dk_plugin
# dragon_knight_flag = True
# except ImportError as e:
# pass
"""
The agent responds to the Arp request.
"""
class ArpRequest(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
_CONTEXTS = {
'fwd': RoutingClass
}
def __init__(self, *args, **kwargs):
super(ArpRequest, self).__init__(*args, **kwargs)
self.fwd = kwargs['fwd']
self.cfg_mgr = BGPSpeakerManager()
self.arp_table = {}
static_arp_table = [{"IP_ADDR": "10.0.0.1", "MAC_ADDR": "00:00:00:00:00:01"}, {"IP_ADDR": "10.0.0.2", "MAC_ADDR": "00:00:00:00:00:02"}]
for addr in static_arp_table:
self.arp_table.setdefault(addr['IP_ADDR'], addr['MAC_ADDR'])
# if dragon_knight_flag:
# dk_plugin.DynamicLoader.register_custom_cmd('arp-proxy:table', self.cmd_dump_arp_table)
# dk_plugin.DynamicLoader.register_custom_cmd('arp-proxy:reload', self.cmd_reload_static)
# dk_plugin.DynamicLoader.register_custom_cmd('arp-proxy:who-has', self.cmd_who_has)
"""
The agent responds to Arp requests in the following situations:
1. The destination host is the local network host:
Find the host, and reply to its Mac address if found;
If it cannot be found, the Arp request will be flooded out.
2. The destination host is BGPSpeaker (including local and external):
Find the host Mac and reply.
3. The destination host is an external network host:
Use the first BGPSpeaker locally as the default gateway and reply to its Mac.
"""
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
@packet_in_filter(RequiredTypeFilter, {'types': [ipv4.ipv4]})
def ipv4_packet_in_handler(self, ev):
msg = ev.msg
pkt = packet.Packet(msg.data)
ethernet_packet_header = pkt.get_protocol(ethernet.ethernet)
ipv4_header = pkt.get_protocol(ipv4.ipv4)
self.arp_table.setdefault(ipv4_header.src, ethernet_packet_header.src)
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
@packet_in_filter(RequiredTypeFilter, {'types': [arp.arp]})
def arp_packet_in_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
in_port = msg.match['in_port']
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
pkt = packet.Packet(data=msg.data)
# self.logger.info("packet-in %s" % (pkt,))
arp_packet_protocol = pkt.get_protocol(arp.arp)
src_ip = arp_packet_protocol.src_ip
src_mac = arp_packet_protocol.src_mac
dst_ip = arp_packet_protocol.dst_ip
dst_mac = None
'''
1. The destination host is the local network host:
Find the host, and reply to its Mac address if found;
If it cannot be found, the Arp request will be flooded out.
2. The destination host is BGPSpeaker (including local and external):
Find the host Mac and reply.
'''
# if self.cfg_mgr.is_internal_host(src_ip):
# # if internal host sent arp request, reply router mac address
# first_speaker_id = None
# if self.cfg_mgr.get_speakers_id():
# first_speaker_id = self.cfg_mgr.get_speakers_id()[0]
# if first_speaker_id:
# dst_mac = self.cfg_mgr.speaker_MAC_Addr(first_speaker_id)
# else:
# dst_mac = self.arp_table.get(dst_ip)
dst_mac = self.arp_table.get(dst_ip)
self.arp_table.setdefault(src_ip, src_mac)
if arp_packet_protocol.opcode != arp.ARP_REQUEST:
return
if not dst_mac:
# can't find distination, drop it
return
# send arp request to host
actions = [parser.OFPActionOutput(in_port)]
arp_reply = packet.Packet()
arp_reply.add_protocol(
ethernet.ethernet(
ethertype=ether_types.ETH_TYPE_ARP,
src=dst_mac,
dst=src_mac
)
)
arp_reply.add_protocol(
arp.arp(
opcode=arp.ARP_REPLY,
src_ip=dst_ip,
src_mac=dst_mac,
dst_ip=src_ip,
dst_mac=src_mac
)
)
arp_reply.serialize()
out = parser.OFPPacketOut(
datapath=datapath,
buffer_id=ofproto.OFP_NO_BUFFER,
in_port=ofproto.OFPP_CONTROLLER,
actions=actions, data=arp_reply.data)
datapath.send_msg(out)
# def cmd_dump_arp_table(self):
# result = "{:<17}{:<17}\n".format("IP", "Mac")
# for record in self.arp_table.items():
# result = result + "{:<17}{:<17}\n".format(record[0], record[1])
# return result
# def cmd_reload_static(self):
# result = ""
# self.arp_table = {}
# if CONF.static_arp_table is not None:
# # load static arp table
# static_arp_table = json.load(open(CONF.static_arp_table, "r"))
# for record in static_arp_table:
# self.arp_table.setdefault(record['ip'], record['mac'])
# result = "done"
# def cmd_who_has(self, *args):
# if len(args) == 0:
# return "Usage: arp-proxy:who-has [IP]"
# arp_req = packet.Packet()
# arp_req.add_protocol(
# ethernet.ethernet(
# ethertype=ether_types.ETH_TYPE_ARP,
# src=DHCP_MAC,
# dst='ff:ff:ff:ff:ff:ff'
# )
# )
# arp_req.add_protocol(
# arp.arp(
# opcode=arp.ARP_REQUEST,
# src_ip=DHCP_IP,
# src_mac=DHCP_MAC,
# dst_ip=src_ip,
# )
# )
# arp_req.serialize()
# for port in self.fwd.get_all_edge_port():
# datapath = self.fwd.get_datapath(port.dpid)
# port_no = port.port_no
# ofproto = datapath.ofproto
# parser = datapath.ofproto_parser
# actions = [parser.OFPActionOutput(port_no)]
# out = parser.OFPPacketOut(
# datapath=datapath,
# buffer_id=ofproto.OFP_NO_BUFFER,
# in_port=ofproto.OFPP_CONTROLLER,
# actions=actions, data=arp_req.data)
# datapath.send_msg(out)
# return "Done"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment