Compare commits

...

21 Commits

Author SHA1 Message Date
FUJITA Tomonori
b0e553d26a add traceroute source ip registration api
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-11 13:32:03 -07:00
Isaku Yamahata
82b919b86f packet lib: packet class supports get_protocol method
returns a list of protocols that matches to the specified protocol.

Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:22 -07:00
Isaku Yamahata
6cc2c48016 packet lib: add Packet.__contains__
you can do something like:
  if arp.arp in Packet(msg.data):

  a = arp.arp(...)
  if a in Packet(msg.data):

  >>> from ryu.lib.packet import packet
  >>> from ryu.lib.packet import arp
  >>> a = arp.arp_ip(1, 0, 0, 0, 0)
  >>> p = packet.Packet()
  >>> p.protocols = [a]
  >>> arp.arp in p
  True
  >>> a in p
  True

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:22 -07:00
FUJITA Tomonori
da5c7f13cf packet lib: packet class accepts protocols list argument
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:12 -07:00
FUJITA Tomonori
00261be526 packet lib: arp default args
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:12 -07:00
FUJITA Tomonori
30a91a81a3 packet lib: vlan default args
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:12 -07:00
FUJITA Tomonori
8b35d7ea34 packet lib: mpls default args
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:12 -07:00
FUJITA Tomonori
edcac1674d packet lib: ipv4 default args
Make ipv4 more handy by not asking for every args. I prefer to use
more human-readble representation for src and dst but it leads to the
API change so let's do it later with another patch.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:12 -07:00
FUJITA Tomonori
d33ef49213 packet lib: icmp support time exceeded type
Used mainly for traceroute.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:23:12 -07:00
Shaun Crampton
e89eb36465 packet lib: allow packet type to be specified when parsing packet
Signed-off-by: Shaun Crampton <Shaun.Crampton@metaswitch.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:22:56 -07:00
Shaun Crampton
5b9e46a8fc packet lib: For convenience, make packet into a sequence type
Protocols can mow be accesed as packet[n].

Signed-off-by: Shaun Crampton <Shaun.Crampton@metaswitch.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-10 09:22:52 -07:00
FUJITA Tomonori
a9c2562015 disable sending all events
Some events can't converted into RPC properly yet.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-05 10:32:01 -07:00
FUJITA Tomonori
d9a30240db fix rpc match
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-06-05 07:14:26 +09:00
FUJITA Tomonori
ce6abfa776 Revert "of1.2: Fix MTVlanVid() parser and serializer"
This reverts commit 6afa1c35ec0a0b2c66c22b6521be9886397aa1df.

You need this change when you use osrg's mpls-of12 repository:

https://github.com/osrg/openvswitch/tree/mpls-of12

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-28 14:29:28 +09:00
FUJITA Tomonori
b35444955d rpc api: support matchfield, match set_with_mask
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-28 14:02:05 +09:00
FUJITA Tomonori
d76b53127d send all OFP events as notificaiton
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-12 13:34:10 -07:00
FUJITA Tomonori
da393e8e3d ofproto_parser: add ofp_attr function
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-12 00:10:43 -07:00
FUJITA Tomonori
0a11bf61ba get all of events
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-11 23:56:53 -07:00
FUJITA Tomonori
389e933d30 add the feature to get all events
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-11 23:56:53 -07:00
FUJITA Tomonori
11f8ab87a0 add of-wire rpc api
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-11 23:56:53 -07:00
FUJITA Tomonori
8948e3e7c1 add simple rpc helper
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
2013-05-11 23:56:53 -07:00
12 changed files with 441 additions and 31 deletions

View File

@ -58,7 +58,9 @@ class RyuApp(object):
super(RyuApp, self).__init__() super(RyuApp, self).__init__()
self.name = self.__class__.__name__ self.name = self.__class__.__name__
self.event_handlers = {} self.event_handlers = {}
self.all_events_handlers = []
self.observers = {} self.observers = {}
self.observers_all = []
self.threads = [] self.threads = []
self.events = hub.Queue(128) self.events = hub.Queue(128)
self.replies = hub.Queue() self.replies = hub.Queue()
@ -67,6 +69,9 @@ class RyuApp(object):
def register_handler(self, ev_cls, handler): def register_handler(self, ev_cls, handler):
assert callable(handler) assert callable(handler)
if ev_cls is None:
self.all_events_handlers.append(handler)
else:
self.event_handlers.setdefault(ev_cls, []) self.event_handlers.setdefault(ev_cls, [])
self.event_handlers[ev_cls].append(handler) self.event_handlers[ev_cls].append(handler)
@ -74,8 +79,12 @@ class RyuApp(object):
states = states or [] states = states or []
self.observers.setdefault(ev_cls, {})[name] = states self.observers.setdefault(ev_cls, {})[name] = states
def register_observer_all(self, name):
self.observers_all.append(name)
def get_handlers(self, ev): def get_handlers(self, ev):
return self.event_handlers.get(ev.__class__, []) handlers = self.event_handlers.get(ev.__class__, [])
return set(self.all_events_handlers) | set(handlers)
def get_observers(self, ev, state): def get_observers(self, ev, state):
observers = [] observers = []
@ -118,7 +127,9 @@ class RyuApp(object):
(self.name, name, ev.__class__.__name__)) (self.name, name, ev.__class__.__name__))
def send_event_to_observers(self, ev, state=None): def send_event_to_observers(self, ev, state=None):
for observer in self.get_observers(ev, state): observers = set(self.get_observers(ev, state))
observers |= set(self.observers_all)
for observer in observers:
self.send_event(observer, ev) self.send_event(observer, ev)
def reply_to_request(self, req, rep): def reply_to_request(self, req, rep):
@ -220,6 +231,14 @@ class AppManager(object):
brick.register_observer(m.ev_cls, i.name, brick.register_observer(m.ev_cls, i.name,
m.dispatchers) m.dispatchers)
for _k, m in inspect.getmembers(i, inspect.ismethod):
if not hasattr(m, 'observer_all'):
continue
name = m.observer_all
if name in SERVICE_BRICKS:
brick = SERVICE_BRICKS[name]
brick.register_observer_all(i.name)
for brick, i in SERVICE_BRICKS.items(): for brick, i in SERVICE_BRICKS.items():
LOG.debug("BRICK %s" % brick) LOG.debug("BRICK %s" % brick)
for ev_cls, list in i.observers.items(): for ev_cls, list in i.observers.items():

293
ryu/controller/api.py Normal file
View File

@ -0,0 +1,293 @@
import eventlet
import sys
import inspect
import netaddr
from ryu.base import app_manager
from ryu.controller import handler
from ryu.controller import dpset
from ryu.controller import ofp_event
from ryu.ofproto.ofproto_parser import MsgBase
from ryu.lib.rpc import RpcSession, RpcMessage
from ryu.ofproto import ofproto_parser
from ryu.ofproto import ofproto_v1_0
from ryu.ofproto import ofproto_v1_0_parser
from ryu.ofproto import ofproto_v1_2
from ryu.ofproto import ofproto_v1_2_parser
from ryu.ofproto import ofproto_v1_3
from ryu.ofproto import ofproto_v1_3_parser
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import arp
from ryu.lib.packet import vlan
from ryu.lib.packet import ipv4
from ryu.lib.packet import ipv6
from ryu.lib.packet import udp
from ryu.lib.packet import tcp
from ryu.lib.packet import icmp
from ryu.lib import mac
from ryu.lib import ip as ip_lib
import netaddr
import array
def find_ofp_cls(ofp_version, name):
parser_name = 'ryu.ofproto.ofproto_v1_' + str(ofp_version - 1) + \
'_parser'
mod = sys.modules[parser_name]
for i in inspect.getmembers(mod, lambda cls: (inspect.isclass(cls))):
if i[0] == name:
return i[1]
return None
traceroute_source = {}
class OFWireRpcSession(object):
def __init__(self, socket, dpset):
self.socket = socket
self.dpset = dpset
self.session = RpcSession()
self.pool = eventlet.GreenPool()
self.send_queue = eventlet.queue.Queue()
self.pool.spawn_n(self._send)
def _send(self):
while True:
m = self.send_queue.get()
self.socket.sendall(m)
def _ofp_handle_matchfield(self, clses, params):
matchfield = getattr(clses, 'make')(**params)
return matchfield
def _ofp_handle_match(self, clses, params):
match = clses()
for k, v in params.items():
if hasattr(match, 'set_' + k):
if k.startswith('ipv4_') or k.startswith('arp_spa') or k.startswith('arp_tpa'):
if k.endswith('_masked'):
addr = netaddr.IPNetwork(v).ip
mask = netaddr.IPNetwork(v).netmask
getattr(match, 'set_' + k)(int(addr), int(mask))
continue
else:
v = int(netaddr.IPNetwork(v).ip)
getattr(match, 'set_' + k)(v)
return match
def _ofp_handle_params(self, dp, params):
for k, v in params.items():
if type(v) == dict:
self._ofp_handle_params(dp, v)
clses = find_ofp_cls(dp.ofproto.OFP_VERSION, k)
if clses is not None:
if issubclass(clses, MsgBase):
ins = clses(dp, **v)
else:
if k == 'OFPMatch' and dp.ofproto.OFP_VERSION > 2:
ins = self._ofp_handle_match(clses, v)
elif k == 'OFPMatchField':
ins = self._ofp_handle_matchfield(clses, v)
else:
ins = clses(**v)
params[k] = ins
return ins
else:
for key, value in v.items():
params[k] = value
break
elif type(v) == list:
ins = []
for i in v:
ins.append(self._ofp_handle_params(dp, i))
params[k] = ins
else:
pass
def ofp_handle_request(self, msg):
dpid = msg[3][0]
params = msg[3][1]
dp = self.dpset.get(int(dpid))
if dp is None:
# hack
for k, v in self.dpset.get_all():
dp = v
break
self._ofp_handle_params(dp, params)
result = {}
for k, v in params.items():
dp.send_msg(v)
result = {'xid': v.xid}
r = self.session.create_response(msg[1], 0, result)
self.send_queue.put(r)
def _tr_handle_notify(self, msg):
params = msg[2][0]
traceroute_source[params['vlan']] = {
'ip': params['ip'],
'port': params['port']
}
print traceroute_source
def serve(self):
while True:
ret = self.socket.recv(4096)
if len(ret) == 0:
break
messages = self.session.get_messages(ret)
for m in messages:
if m[0] == RpcMessage.REQUEST:
if m[2] == 'ofp':
self.ofp_handle_request(m)
elif m[0] == RpcMessage.RESPONSE:
pass
elif m[0] == RpcMessage.NOTIFY:
if m[1] == 'traceroute':
self._tr_handle_notify(m)
else:
print "invalid type", m
class RPCApi(app_manager.RyuApp):
_CONTEXTS = {
'dpset': dpset.DPSet,
}
def __init__(self, *args, **kwargs):
self.dpset = kwargs['dpset']
super(RPCApi, self).__init__(*args, **kwargs)
self.server = eventlet.listen(('', 50001))
self.pool = eventlet.GreenPool()
self.pool.spawn_n(self.serve)
self.sessions = []
def serve(self):
while True:
sock, address = self.server.accept()
session = OFWireRpcSession(sock, self.dpset)
self.sessions.append(session)
self.pool.spawn_n(session.serve)
def _ofp_handle_ob(self, dp, msg, params):
clses = find_ofp_cls(dp.ofproto.OFP_VERSION,
msg.__class__.__name__)
if clses:
params[msg.__class__.__name__] = {}
_params = params[msg.__class__.__name__]
else:
_params = params
for i in ofproto_parser.ofp_attr(msg):
if i.startswith('_'):
continue
elif i == 'parser':
continue
elif i == 'serialize':
continue
v = getattr(msg, i)
if type(v) == dict:
_params[i] = {}
for key in v.keys():
_params[i][key] = {}
self._ofp_handle_ob(dp, v[key], _params[i][key])
elif type(v) == list:
ins = []
for j in v:
d = {}
self._ofp_handle_ob(dp, j, d)
ins.append(d)
_params[i] = ins
elif type(v).__name__ == 'builtin_function_or_method':
pass
else:
_params[i] = v
# @handler.observe_all_events('ofp_event')
# def _handler(self, ev):
# if hasattr(ev, 'msg'):
# ofmsg = ev.msg
# params = {}
# self._ofp_handle_ob(ofmsg.datapath, ofmsg, params)
# for k in params.keys():
# params[k]['xid'] = ofmsg.xid
# # for s in self.sessions:
# # m = s.session.create_notification('ofp', params)
# # s.send_queue.put(m)
def handle_traceroute(self, msg):
dp = msg.datapath
in_port = None
for f in msg.match.fields:
if f.header == ofproto_v1_2.OXM_OF_IN_PORT:
in_port = f.value
if in_port is None:
print "in_port is missing"
return
pkt = packet.Packet(msg.data)
if not ipv4.ipv4 in pkt:
print "ip header doesn't exit"
return
if vlan.vlan in pkt:
o_vlan = pkt.get_protocols(vlan.vlan)[0]
vlan_p = vlan.vlan(vid=o_vlan.vid)
else:
print "vlan header doesn't exit"
return
o_eth = pkt.get_protocols(ethernet.ethernet)[0]
print mac.haddr_to_str(o_eth.dst), mac.haddr_to_str(o_eth.src)
eth = ethernet.ethernet(o_eth.src, o_eth.dst, o_eth.ethertype)
o_ip = pkt.get_protocols(ipv4.ipv4)[0]
print ip_lib.ipv4_to_str(o_ip.dst), ip_lib.ipv4_to_str(o_ip.src)
# needs to set src properly for either side (vlan or mpls)
# ip = ipv4.ipv4(src=ip_lib.ipv4_to_bin(V1_GS_IP), dst=o_ip.src,
# proto=1)
src_ip = traceroute_source[o_vlan.vid]['ip']
in_port = traceroute_source[o_vlan.vid]['port']
ip = ipv4.ipv4(src=ip_lib.ipv4_to_bin(src_ip), dst=o_ip.src, proto=1)
ip_offset = o_eth.length
# vlan header
ip_offset += 4
data = msg.data[ip_offset:ip_offset +
(o_ip.header_length * 4 + 8)]
ic = icmp.icmp(icmp.ICMP_TIME_EXCEEDED, 0, 0,
icmp.TimeExceeded(data))
proto_list = [eth, vlan_p, ip, ic]
p = packet.Packet(protocols=proto_list)
p.serialize()
self.send_openflow_packet(dp=dp, packet=p.data,
port_no=ofproto_v1_2.OFPP_TABLE,
inport=in_port)
def send_openflow_packet(self, dp, packet, port_no,
inport=ofproto_v1_2.OFPP_CONTROLLER):
actions = [dp.ofproto_parser.OFPActionOutput(port_no, 0)]
dp.send_packet_out(in_port=inport, actions=actions, data=packet)
@handler.set_ev_cls(ofp_event.EventOFPPacketIn)
def packet_in_handler(self, ev):
msg = ev.msg
print "trace"
if ofproto_v1_2.OFPR_INVALID_TTL == msg.reason:
print "zero ttl packet"
self.handle_traceroute(msg)
return
@handler.set_ev_cls(dpset.EventDP)
def handler_datapath(self, ev):
print "join"
if ev.enter:
print "dp joined"
dp = ev.dp
m = dp.ofproto_parser.OFPSetConfig(dp, 1 << 2, miss_send_len=1600)
dp.send_msg(m)

View File

@ -46,6 +46,13 @@ def set_ev_handler(ev_cls, dispatchers=None):
return _set_ev_cls_dec return _set_ev_cls_dec
def observe_all_events(source):
def _set_ev_cls_dec(handler):
handler.observer_all = source
return handler
return _set_ev_cls_dec
def _is_ev_cls(meth): def _is_ev_cls(meth):
return hasattr(meth, 'ev_cls') return hasattr(meth, 'ev_cls')
@ -63,3 +70,5 @@ def register_instance(i):
# LOG.debug('instance %s k %s m %s', i, _k, m) # LOG.debug('instance %s k %s m %s', i, _k, m)
if _is_ev_cls(m): if _is_ev_cls(m):
i.register_handler(m.ev_cls, m) i.register_handler(m.ev_cls, m)
elif hasattr(m, 'observer_all'):
i.register_handler(None, m)

View File

@ -16,6 +16,8 @@
import struct import struct
from ryu.ofproto import ether from ryu.ofproto import ether
from ryu.lib import ip
from ryu.lib import mac
from . import packet_base from . import packet_base
ARP_HW_TYPE_ETHERNET = 1 # ethernet hardware type ARP_HW_TYPE_ETHERNET = 1 # ethernet hardware type
@ -52,8 +54,12 @@ class arp(packet_base.PacketBase):
_PACK_STR = '!HHBBH6sI6sI' _PACK_STR = '!HHBBH6sI6sI'
_MIN_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = struct.calcsize(_PACK_STR)
def __init__(self, hwtype, proto, hlen, plen, opcode, def __init__(self, hwtype=ARP_HW_TYPE_ETHERNET, proto=ether.ETH_TYPE_IP,
src_mac, src_ip, dst_mac, dst_ip): hlen=6, plen=4, opcode=ARP_REQUEST,
src_mac=mac.haddr_to_bin('ff:ff:ff:ff:ff:ff'),
src_ip=ip.ipv4_to_bin('0.0.0.0'),
dst_mac=mac.haddr_to_bin('ff:ff:ff:ff:ff:ff'),
dst_ip=ip.ipv4_to_bin('0.0.0.0')):
super(arp, self).__init__() super(arp, self).__init__()
self.hwtype = hwtype self.hwtype = hwtype
self.proto = proto self.proto = proto

View File

@ -24,6 +24,7 @@ ICMP_DEST_UNREACH = 3
ICMP_SRC_QUENCH = 4 ICMP_SRC_QUENCH = 4
ICMP_REDIRECT = 5 ICMP_REDIRECT = 5
ICMP_ECHO_REQUEST = 8 ICMP_ECHO_REQUEST = 8
ICMP_TIME_EXCEEDED = 11
class icmp(packet_base.PacketBase): class icmp(packet_base.PacketBase):
@ -146,3 +147,20 @@ class echo(object):
hdr += self.data hdr += self.data
return hdr return hdr
@icmp.register_icmp_type(ICMP_TIME_EXCEEDED)
class TimeExceeded(object):
_PACK_STR = '!4x'
_MIN_LEN = struct.calcsize(_PACK_STR)
def __init__(self, data=None):
self.data = data
def serialize(self):
hdr = bytearray(TimeExceeded._MIN_LEN)
if self.data is not None:
hdr += self.data
return hdr

View File

@ -21,6 +21,7 @@ from . import icmp
from . import udp from . import udp
from . import tcp from . import tcp
from ryu.ofproto import inet from ryu.ofproto import inet
from ryu.lib import ip
IPV4_ADDRESS_PACK_STR = '!I' IPV4_ADDRESS_PACK_STR = '!I'
@ -64,9 +65,12 @@ class ipv4(packet_base.PacketBase):
_PACK_STR = '!BBHHHBBHII' _PACK_STR = '!BBHHHBBHII'
_MIN_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = struct.calcsize(_PACK_STR)
def __init__(self, version, header_length, tos, total_length, def __init__(self, version=4, header_length=5, tos=0,
identification, flags, offset, ttl, proto, csum, total_length=0, identification=0, flags=0,
src, dst, option=None): offset=0, ttl=255, proto=0, csum=0,
src=ip.ipv4_to_bin('0.0.0.0'),
dst=ip.ipv4_to_bin('0.0.0.0'),
option=None):
super(ipv4, self).__init__() super(ipv4, self).__init__()
self.version = version self.version = version
self.header_length = header_length self.header_length = header_length

View File

@ -44,7 +44,7 @@ class mpls(packet_base.PacketBase):
_PACK_STR = '!I' _PACK_STR = '!I'
_MIN_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = struct.calcsize(_PACK_STR)
def __init__(self, label, exp, bsb, ttl): def __init__(self, label=0, exp=0, bsb=1, ttl=255):
super(mpls, self).__init__() super(mpls, self).__init__()
self.label = label self.label = label
self.exp = exp self.exp = exp

View File

@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import inspect
from . import packet_base from . import packet_base
from . import ethernet from . import ethernet
@ -31,15 +33,17 @@ class Packet(object):
*data* should be omitted when encoding a packet. *data* should be omitted when encoding a packet.
""" """
def __init__(self, data=None): def __init__(self, data=None, protocols=None, parse_cls=ethernet.ethernet):
super(Packet, self).__init__() super(Packet, self).__init__()
self.data = data self.data = data
if protocols is None:
self.protocols = [] self.protocols = []
else:
self.protocols = protocols
self.protocol_idx = 0 self.protocol_idx = 0
self.parsed_bytes = 0 self.parsed_bytes = 0
if self.data: if self.data:
# Do we need to handle non ethernet? self._parser(parse_cls)
self._parser(ethernet.ethernet)
def _parser(self, cls): def _parser(self, cls):
while cls: while cls:
@ -83,6 +87,14 @@ class Packet(object):
self.protocols.append(proto) self.protocols.append(proto)
def get_protocols(self, protocol):
"""Returns a list of protocols that matches to the specified protocol.
"""
if isinstance(protocol, packet_base.PacketBase):
protocol = protocol.__class__
assert issubclass(protocol, packet_base.PacketBase)
return [p for p in self.protocols if isinstance(p, protocol)]
def next(self): def next(self):
try: try:
p = self.protocols[self.protocol_idx] p = self.protocols[self.protocol_idx]
@ -95,3 +107,21 @@ class Packet(object):
def __iter__(self): def __iter__(self):
return self return self
def __getitem__(self, idx):
return self.protocols[idx]
def __setitem__(self, idx, item):
self.protocols[idx] = item
def __delitem__(self, idx):
del self.protocols[idx]
def __len__(self):
return len(self.protocols)
def __contains__(self, protocol):
if (inspect.isclass(protocol) and
issubclass(protocol, packet_base.PacketBase)):
return protocol in [p.__class__ for p in self.protocols]
return protocol in self.protocols

View File

@ -43,7 +43,7 @@ class vlan(packet_base.PacketBase):
_PACK_STR = "!HH" _PACK_STR = "!HH"
_MIN_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = struct.calcsize(_PACK_STR)
def __init__(self, pcp, cfi, vid, ethertype): def __init__(self, pcp=0, cfi=0, vid=0, ethertype=ether.ETH_TYPE_IP):
super(vlan, self).__init__() super(vlan, self).__init__()
self.pcp = pcp self.pcp = pcp
self.cfi = cfi self.cfi = cfi

37
ryu/lib/rpc.py Normal file
View File

@ -0,0 +1,37 @@
import msgpack
class RpcMessage(object):
REQUEST = 0
RESPONSE = 1
NOTIFY = 2
class RpcSession(object):
def __init__(self):
super(RpcSession, self).__init__()
self._packer = msgpack.Packer()
self._unpacker = msgpack.Unpacker()
self._next_msgid = 0
def _create_msgid(self):
this_id = self._next_msgid
self._next_msgid += 1
return this_id
def create_request(self, method, params):
msgid = self._create_msgid()
return self._packer.pack([RpcMessage.REQUEST, msgid, method, params])
def create_response(self, msgid, error, result):
return self._packer.pack([RpcMessage.RESPONSE, msgid, error, result])
def create_notification(self, method, params):
return self._packer.pack([RpcMessage.NOTIFY, method, params])
def get_messages(self, data):
self._unpacker.feed(data)
messages = []
for msg in self._unpacker:
messages.append(msg)
return messages

View File

@ -147,14 +147,18 @@ def msg_pack_into(fmt, buf, offset, *args):
struct.pack_into(fmt, buf, offset, *args) struct.pack_into(fmt, buf, offset, *args)
def msg_str_attr(msg, buf, attr_list=None): def ofp_attr(msg):
if attr_list is None:
exclude = ['_attributes'] exclude = ['_attributes']
try: try:
exclude += msg._attributes exclude += msg._attributes
except AttributeError: except AttributeError:
pass pass
attr_list = set(dir(msg)) - set(exclude) return set(dir(msg)) - set(exclude)
def msg_str_attr(msg, buf, attr_list=None):
if attr_list is None:
attr_list = ofp_attr(msg)
for attr in attr_list: for attr in attr_list:
val = getattr(msg, attr, None) val = getattr(msg, attr, None)
if val is not None: if val is not None:

View File

@ -2104,16 +2104,6 @@ class MTVlanVid(OFPMatchField):
self.value = value self.value = value
self.mask = mask self.mask = mask
@classmethod
def field_parser(cls, header, buf, offset):
m = super(MTVlanVid, cls).field_parser(header, buf, offset)
m.value &= ~ofproto_v1_2.OFPVID_PRESENT
return m
def serialize(self, buf, offset):
self.value |= ofproto_v1_2.OFPVID_PRESENT
super(MTVlanVid, self).serialize(buf, offset)
@OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_VLAN_PCP]) @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_VLAN_PCP])
class MTVlanPcp(OFPMatchField): class MTVlanPcp(OFPMatchField):