📅  最后修改于: 2023-12-03 14:47:21.119000             🧑  作者: Mango
SDN(Software-Defined Networking,软件定义网络)是将网络控制平面(control plane)与数据平面(data plane)分离的一种网络架构,其中控制平面由计算机程序控制,而数据平面是随时转发网络数据包的硬件部分。
SDN控制器是SDN架构中的核心组件,负责控制网络中各个设备的行为,如路由、转发、QoS(Quality of Service,服务质量)等。本文将介绍两个常用的SDN控制器:Ryu和OpenDaylight。
Ryu是一个日本制作的开源SDN控制器,由Python编写,采用BSD协议。Ryu提供了丰富的API,使得程序员可以方便地使用Python编写SDN程序。Ryu的特点包括:
以下是使用Ryu Python API实现一个简单交换机的示例代码:
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, DEAD_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 SimpleSwitch(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(SimpleSwitch, self).__init__(*args, **kwargs)
self.mac_to_port = {}
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, MAIN_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
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
eth = pkt.get_protocols(ethernet.ethernet)[0]
dst = eth.dst
src = eth.src
dpid = datapath.id
self.mac_to_port.setdefault(dpid, {})
self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
# learn a mac address to avoid FLOOD next time.
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)]
# install a flow to avoid packet_in next time
if out_port != ofproto.OFPP_FLOOD:
match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
self.add_flow(datapath, 1, match, actions)
data = None
if msg.buffer_id == ofproto.OFP_NO_BUFFER:
data = msg.data
out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
in_port=in_port, actions=actions, data=data)
datapath.send_msg(out)
@set_ev_cls(ofp_event.EventOFPStateChange,
[MAIN_DISPATCHER, DEAD_DISPATCHER])
def state_change_handler(self, ev):
datapath = ev.datapath
if ev.state == MAIN_DISPATCHER:
if not datapath.id in self.mac_to_port:
self.mac_to_port[datapath.id] = {}
self.logger.info('switch joined: %s', datapath.id)
elif ev.state == DEAD_DISPATCHER:
self.logger.info('switch left: %s', datapath.id)
if datapath.id in self.mac_to_port:
del self.mac_to_port[datapath.id]
OpenDaylight(ODL)是一个由Linux基金会支持的、以Java编写的、开源的SDN控制器。ODL提供了一种通用的框架,使得用户可以创建、管理和调度SDN网络。ODL的特点包括:
以下是使用ODL REST API查询网络拓扑的示例代码:
import requests
import json
def get_topology():
url = 'http://127.0.0.1:8181/restconf/operational/network-topology:network-topology'
headers = {
'Authorization': 'Basic YWRtaW46YWRtaW4=',
'Content-type': 'application/json'
}
response = requests.get(url, headers=headers)
data = json.loads(response.text)
topology = data['network-topology']['topology'][0]['node']
for node in topology:
print('Node:', node['node-id'])
for link in node['termination-point']:
print(' Link:', link['tp-id'], 'to', link['remote-system']['system-id'] + '/' + link['remote-system']['node-id'] + '/' + link['remote-tp'])
通过使用SDN控制器,程序员可以实现更加灵活、高效的网络编程,为网络运营和管理带来了巨大的变革。以上是介绍两个常用的SDN控制器,有助于程序员们更好地了解和使用SDN技术。