Python local variable losing reference - python

I'm developing a SDN Controller with Ryu Framework in Python.
I'm facing a strange problem, maybe an easy one since it's my first time programming in Python. I have the following sentence:
#set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
# If you hit this you might want to increase
# the "miss_send_length" of your switch
if ev.msg.msg_len < ev.msg.total_len:
self.logger.debug("packet truncated: only %s of %s bytes",
ev.msg.msg_len, ev.msg.total_len)
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]
pkt_ip = pkt.get_protocol(ipv4.ipv4)
ipv4_src = None
ipv4_dst = None
if pkt_ip is not None:
print "pkt_ip is not none"
ipv4_src = pkt_ip.src
ipv4_dst = pkt_ip.dst
print ipv4_src
print ipv4_dst
if eth.ethertype == ether_types.ETH_TYPE_LLDP:
# ignore lldp packet
return
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)
self.logger.info("learn a mac address")
# 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)]
#print "before avoid packet_in"
#print ipv4_src
# install a flow to avoid packet_in next time
self.logger.info("install a flow to avoid packet_in next time")
if out_port != ofproto.OFPP_FLOOD:
print "into if out_port"
print ipv4_src
print in_port
print dst
match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
# verify if we have a valid buffer_id, if yes avoid to send both
# flow_mod & packet_out
if msg.buffer_id != ofproto.OFP_NO_BUFFER:
self.add_flow(datapath, 1, match, actions, msg.buffer_id)
return
else:
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)
self.logger.info("send_msg_out")
print out
datapath.send_msg(out)
self.logger.info("sent send_msg_out in packet_in")
When I am not passing ipv4_src as parameter ( match = parser.OFPMatch(in_port=in_port, eth_dst=dst) ), the code runs ok. The variables are printed and no errors.
However, when I'm passing ipv4_src as parameter ( match = parser.OFPMatch(in_port=in_port, eth_dst=dst ipv4_src=ipv4_src) ), I always get 'None' in the print dst and the parser.OFPMatch returns me a length error (of course, as it is getting 'None').
Independently of using ipv4_src as parameter in parser.OFPMatch, in_port and dst are always printed succesfully.
Does it have something to do with some Python characteristic I'm skipping?
EDITED:
See two output examples:
Not using ipv4_src as parameter:
into if out_port
192.168.1.200
2
00:00:00:00:00:01
Using ipv4_src as parameter:
into if out_port
None
2
00:00:00:00:00:01
When I use ipv4_src I get the following (because the method is getting 'None' it cannot get his length, I suppose):
into if out_port
None
1
00:00:00:00:00:02
SimpleSwitch13: Exception occurred during handler processing. Backtrace from offending handler [_packet_in_handler] servicing event [EventOFPPacketIn] follows.
Traceback (most recent call last):
File "/home/ryu/ryu/ryu/base/app_manager.py", line 290, in _event_loop
handler(ev)
File "/home/ryu/ryu/ryu/app/simple_switch_13.py", line 134, in _packet_in_handler
self.add_flow(datapath, 1, match, actions, msg.buffer_id)
File "/home/ryu/ryu/ryu/app/simple_switch_13.py", line 68, in add_flow
datapath.send_msg(mod)
File "/home/ryu/ryu/ryu/controller/controller.py", line 289, in send_msg
msg.serialize()
File "/home/ryu/ryu/ryu/ofproto/ofproto_parser.py", line 211, in serialize
self._serialize_body()
File "/home/ryu/ryu/ryu/ofproto/ofproto_v1_3_parser.py", line 2655, in _serialize_body
match_len = self.match.serialize(self.buf, offset)
File "/home/ryu/ryu/ryu/ofproto/ofproto_v1_3_parser.py", line 1008, in serialize
field_offset)
File "/home/ryu/ryu/ryu/ofproto/oxx_fields.py", line 250, in _serialize
value_len = len(value)
TypeError: object of type 'NoneType' has no len()

Related

pytest: TypeError: int() can't convert non-string with explicit base

def _get_trace(self) -> None:
"""Retrieves the stack trace via debug_traceTransaction and finds the
return value, revert message and event logs in the trace.
"""
# check if trace has already been retrieved, or the tx warrants it
if self._raw_trace is not None:
return
self._raw_trace = []
if self.input == "0x" and self.gas_used == 21000:
self._modified_state = False
self._trace = []
return
if not web3.supports_traces:
raise RPCRequestError("Node client does not support `debug_traceTransaction`")
try:
trace = web3.provider.make_request( # type: ignore
"debug_traceTransaction", (self.txid, {"disableStorage": CONFIG.mode != "console"})
)
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
msg = f"Encountered a {type(e).__name__} while requesting "
msg += "`debug_traceTransaction`. The local RPC client has likely crashed."
if CONFIG.argv["coverage"]:
msg += " If the error persists, add the `skip_coverage` marker to this test."
raise RPCRequestError(msg) from None
if "error" in trace:
self._modified_state = None
self._trace_exc = RPCRequestError(trace["error"]["message"])
raise self._trace_exc
self._raw_trace = trace = trace["result"]["structLogs"]
if not trace:
self._modified_state = False
return
# different nodes return slightly different formats. its really fun to handle
# geth/nethermind returns unprefixed and with 0-padding for stack and memory
# erigon returns 0x-prefixed and without padding (but their memory values are like geth)
fix_stack = False
for step in trace:
if not step["stack"]:
continue
check = step["stack"][0]
if not isinstance(check, str):
break
if check.startswith("0x"):
fix_stack = True
> c:\users\xxxx\appdata\local\programs\python\python310\lib\site-packages\brownie\network\transaction.py(678)_get_trace()
-> step["pc"] = int(step["pc"], 16)
(Pdb)
I am doing Patricks Solidity course and ran into this error. I ended up copying and pasting his code:
def test_only_owner_can_withdraw():
if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
pytest.skip("only for local testing")
fund_me = deploy_fund_me()
bad_actor = accounts.add()
with pytest.raises(exceptions.VirtualMachineError):
fund_me.withdraw({"from": bad_actor})
Pytest worked for my other tests however When I tried to do this one it wouldnt work.
Ok, So after looking at my scripts and contracts I found the issue. The was an issue with my .sol contract and instead of returning a variable, it was returning the error message from my retrieve function in the contract. Its fixed and working now

Python script to check bond status for Linux

I have the Below python code which I'm using to determine the Linux bond/team status. This code works just fine. I am not good at aligning the output formatting thus getting little hiccup.
I wanted the Printing Format into a Certain format, would appreciate any help on the same.
Below is the code exercise:
#!/usr/bin/python
# Using below file to process the data
# cat /proc/net/bonding/bond0
import sys
import re
def usage():
print '''USAGE: %s [options] [bond_interface]
Options:
--help, -h This usage document
Arguments:
bond_interface The bonding interface to query, eg. 'bond0'. Default is 'bond0'.
''' % (sys.argv[0])
sys.exit(1)
# Parse arguments
try:
iface = sys.argv[1]
if iface in ('--help', '-h'):
usage()
except IndexError:
iface = 'bond0'
# Grab the inf0z from /proc
try:
bond = open('/proc/net/bonding/%s' % iface).read()
except IOError:
print "ERROR: Invalid interface %s\n" % iface
usage()
# Parse and output
active = 'NONE'
Link = 'NONE'
slaves = ''
state = 'OK'
links = ''
bond_status = ''
for line in bond.splitlines():
m = re.match('^Currently Active Slave: (.*)', line)
if m:
active = m.groups()[0]
m = re.match('^Slave Interface: (.*)', line)
if m:
s = m.groups()[0]
slaves += ', %s' % s
m = re.match('^Link Failure Count: (.*)', line)
if m:
l = m.groups()[0]
links += ', %s' % l
m = re.match('^MII Status: (.*)', line)
if m:
s = m.groups()[0]
if slaves == '':
bond_status = s
else:
slaves += ' %s' % s
if s != 'up':
state = 'FAULT'
print "%s %s (%s) %s %s %s" % (iface, state, bond_status, active, slaves, links)
Result:
$ ./bondCheck.py
bond0 OK (up) ens3f0 , ens3f0 up, ens3f1 up , 0, 0
Expected:
bond0: OK (up), Active Slave: ens3f0 , PriSlave: ens3f0(up), SecSlave: ens3f1(up) , LinkFailCountOnPriInt: 0, LinkFailCountOnSecInt: 0
I tried to format in a very basic way as shown below :
print "%s: %s (%s), Active Slave: %s, PriSlave: %s (%s), SecSlave: %s (%s), LinkFailCountOnPriInt: %s, LinkFailCountOnSecInt: %s" % (iface, state, bond_status, active, slaves.split(',')[1].split()[0], slaves.split(',')[1].split()[1], slaves.split(',')[2].split()[0], slaves.split(',')[2].split()[1], links.split(',')[1], links.split(',')[2])
RESULT:
bond0: OK (up), Active Slave: ens3f0, PriSlave: ens3f0 (up), SecSlave: ens3f1 (up), LinkFailCountOnPriInt: 1, LinkFailCountOnSecInt: 1
However, I would suggest to get the values into variables prior and then use them in the print statement so as to avoid "out of index" issues during print() , as in rare cases like bond with only one interface will report indexing error while splitting hence good to get the values in variable and suppress the out of index into exception for those cases.
Do not use the way with "/proc/net/bonding/%s' for querying bond status. It could trigger system panic. Try to use "/sys/class/net/bondX/bonding", it is more safe.

HSM using label of key object in PKCS11

This block of code is loading a cryptoki.so library and retrieving slot info. This is getting a list of objects in slot num. 0. I don't need to access all the keys to perform a few functions, just a specific key pair. Is there a way to get a single desired token by using the label name, object ID, or handle?
pkcs11 = PyKCS11.PyKCS11Lib()
pkcs11.load(lib)
pkcs11.initialize()
info = pkcs11.getInfo()
i = pkcs11.getSlotInfo(0)
pkcs11.openSession(0)
print "Library manufacturerID: " + info.manufacturerID
slots = pkcs11.getSlotList()
print "Available Slots:", len(slots)
for s in slots:
try:
i = pkcs11.getSlotInfo(s)
print "Slot no:", s
print format_normal % ("slotDescription", i.slotDescription.strip())
print format_normal % ("manufacturerID", i.manufacturerID.strip())
t = pkcs11.getTokenInfo(s)
print "TokenInfo"
print format_normal % ("label", t.label.strip())
print format_normal % ("manufacturerID", t.manufacturerID.strip())
print format_normal % ("model", t.model.strip())
session = pkcs11.openSession(s)
print "Opened session 0x%08X" % session.session.value()
if pin_available:
try:
session.login(pin=pin)
except:
print "login failed, exception:", str(sys.exc_info()[1])
objects = session.findObjects()
print
print "Found %d objects: %s" % (len(objects), [x.value() for x in objects])
The specific script i'm running only has a few commands defined, such as -pin --sign --decrypt --lib do i need to define a common pkcs11-tool such as --init-token or --token-label to pass it as an argument when executing my script ? Or can i directly assign a variable to the desired LabelName within the python script?
So from command line i'm running
$./Test.py --pin=pass and getting the following
Library manufacturerID: Safenet, Inc.
Available Slots: 4
Slot no: 0
slotDescription: ProtectServer K5E:00045
manufacturerID: SafeNet Inc.
TokenInfo
label: CKM
manufacturerID: SafeNet Inc.
model: K5E:PL25
Opened session 0x00000002
Found 52 objects: [5021, 5022, 5014, 5016, 4, 5, 6, 7, 8, 9, 16, 18, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 5313, 5314, 4982, 5325, 5326, 5328, 5329, 5331, 5332, 5335, 5018, 4962, 5020, 4963, 5357, 5358, 5360, 5361, 5363, 5364, 5366, 5367, 5369, 5370, 5372, 5373, 5375, 5376]
I'm ultimately trying to get only one of these objects to run some tests.For instance objectID = 201603040001 contains a private/cert file. I want to specify this particular handle. The actual label is something like 000103...3A0. How can I define this so I don't get the rest of the objects inside the library.
Here's the a list of just a couple of the HSM objects
HANDLE LABEL TYPE OBJECT-ID
5314 00000103000003A1 X509PublicKeyCertificate 201603040001
5313 00000103000003A1 RSAPrivateKey 201603040001
I'm trying to pull just one of the Labels.
Here's the defined usage
def usage():
print "Usage:", sys.argv[0],
print "[-p pin][--pin=pin]",
print "[-s slot][--slot=slot]",
print "[-c lib][--lib=lib]",
print "[-h][--help]",
print "[-o][--opensession]"
try:
opts, args = getopt.getopt(sys.argv[1:], "p:c:Sd:h:s", ["pin=", "lib=", "sign", "decrypt", "help","slot="])
except getopt.GetoptError:
# print help information and exit:
usage()
sys.exit(2)
I'm not aware of how I can add an argument so I can use --sign with just a specific label. End game I want to use $./Test.py --pin=pass --sign --label "00000103000003A4" or by handle $./Test.py --pin=pass --sign --handle=5313
UPDATED from suggested comments below. still having trouble getting attributes for rsa private key and cert. Using the specific token has worked but those objects inside of it are returning bad attribute types
t = pkcs11.getTokenInfo(s)
print "TokenInfo"
if 'CKM' == t.label.decode('ascii').strip():
tokenInfo = pkcs11.getTokenInfo(slot)
if '00000103000003A1' == tokenInfo.label.decode('ascii').strip():
print format_normal % ("label", t.label.strip())
print format_normal % ("manufacturerID", t.manufacturerID.strip())
print format_normal % ("model", t.model.strip())
session = pkcs11.openSession(s)
print("Opened session 0x%08X" % session.session.value())
if pin_available:
try:
if (pin is None) and \
(PyKCS11.CKF_PROTECTED_AUTHENTICATION_PATH & t.flags):
print("\nEnter your PIN for %s on the pinpad" % t.label.strip())
session.login(pin=pin)
except:
print("login failed, exception:", str(sys.exc_info()[1]))
break
objects = session.findObjects([(CKA_LABEL, "00000103000003A4")])
print()
print("Found %d objects: %s" % (len(objects), [x.value() for x in objects]))
all_attributes = list(PyKCS11.CKA.keys())
# only use the integer values and not the strings like 'CKM_RSA_PKCS'
all_attributes.remove(PyKCS11.CKA_PRIVATE_EXPONENT)
all_attributes.remove(PyKCS11.CKA_PRIME_1)
all_attributes.remove(PyKCS11.CKA_PRIME_2)
all_attributes.remove(PyKCS11.CKA_EXPONENT_1)
all_attributes.remove(PyKCS11.CKA_EXPONENT_2)
all_attributes.remove(PyKCS11.CKA_COEFFICIENT)
all_attributes = [e for e in all_attributes if isinstance(e, int)]
n_obj = 1
for o in objects:
print()
print((red + "==================== Object: %d ====================" + normal) % o.value())
n_obj += 1
try:
attributes = session.getAttributeValue(o, all_attributes)
except PyKCS11.PyKCS11Error as e:
continue
attrDict = dict(zip(all_attributes, attributes))
if attrDict[PyKCS11.CKA_CLASS] == PyKCS11.CKO_PRIVATE_KEY \
and attrDict[PyKCS11.CKA_KEY_TYPE] == PyKCS11.CKK_RSA:
m = attrDict[PyKCS11.CKA_MODULUS]
e = attrDict[PyKCS11.CKA_PUBLIC_EXPONENT]
if m and e:
mx = eval(b'0x' + ''.join("%02X" %c for c in m))
ex = eval(b'0x' + ''.join("%02X" %c for c in e))
if sign:
try:
toSign = "12345678901234567890123456789012" # 32 bytes, SHA256 digest
print("* Signing with object 0x%08X following data: %s" % (o.value(), toSign))
signature = session.sign(o, toSign)
sx = eval(b'0x' + ''.join("%02X" % c for c in signature))
print("Signature:")
print(dump(''.join(map(chr, signature))))
if m and e:
print("Verifying using following public key:")
print("Modulus:")
print(dump(''.join(map(chr, m))))
print("Exponent:")
print(dump(''.join(map(chr, e))))
decrypted = pow(sx, ex, mx) # RSA
print("Decrypted:")
d = binascii.unhexlify(hexx(decrypted))
print(dump(d))
if toSign == d[-20:]:
print("*** signature VERIFIED!\n")
the following is what prints. nothing seems to be working using the specific objects, there are no error messages
Slot no: 0
slotDescription: ProtectServer K5E:00045
manufacturerID: SafeNet Inc.
TokenInfo
Opened session 0x00000002
Found 2 objects: [5328, 5329]
==================== Object: 5328 ====================
==================== Object: 5329 ====================
You can work only with one token by checking its label before use, e.g.:
tokenInfo = pkcs11.getTokenInfo(slot)
if 'DesiredTokenLabel' == tokenInfo.label.decode('ascii').strip():
# Start working with this particular token
session = pkcs11.openSession(s)
You can enumerate only specific object using a template argument for the findObjects call, e.g.:
# get objects labelled "PRIV"
objects = session.findObjects([(CKA_LABEL, "PRIV")])
# get all private key objects
objects = session.findObjects([(CKA_CLASS, CKO_PRIVATE_KEY)])
# get all private key objects labelled "PRIV"
objects = session.findObjects([(CKA_CLASS, CKO_PRIVATE_KEY),(CKA_LABEL, "PRIV")])
# get all RSA private key objects labelled "PRIV"
objects = session.findObjects([(CKA_CLASS, CKO_PRIVATE_KEY),(CKA_KEY_TYPE, CKK_RSA),(CKA_LABEL, "PRIV")])
Below is an example code with hard-coded parameters:
from PyKCS11 import *
pkcs11 = PyKCS11.PyKCS11Lib()
pkcs11.load("your module path...")
slots = pkcs11.getSlotList()
for s in slots:
t = pkcs11.getTokenInfo(s)
if 'CKM' == t.label.decode('ascii').strip():
session = pkcs11.openSession(s)
objects = session.findObjects([(CKA_LABEL, "00000103000003A1")])
print ("Found %d objects: %s" % (len(objects), [x.value() for x in objects]))
Please note that it is Python 3 as I can't use PyKCS11 in Python 2.x right now.
Soma additional (random) notes:
do not rely on handles -- they may (and will) be different for different program runs
your program's command line arguments are up to you -- you must decide yourself if your program needs arguments like --token-label
Disclaimer: I am not that into python so please do validate my thoughts
Good luck!
EDIT(Regarding you recent edit)>
No error is (most probably) shown because the exception is caught and ignored:
try:
attributes = session.getAttributeValue(o, all_attributes)
except PyKCS11.PyKCS11Error as e:
continue

PYSNMP: pyasn1.error.SubstrateUnderrunError: 37998-octet short

I have python version 4.3.2, py2exe 0.9.1.0, pysnmp 0.4.3.1, pyans1 0.1.9.
Im encountering all type of inconsistent errors in many different clients.
One of my clients, which has hundreds of SNMP devices, consonantly has pysnmp errors that are preventing him from discovering all snmp devices.
This is the function:
def cbFun_Device(transportDispatcher, transportDomain, transportAddress, wholeMsg):
while wholeMsg:
for ip in Device.scan.devices:
if ip == transportAddress[0]:
try:
PDU = Device.scan.devices[ip].PDU
rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec = PDU['pMod'].Message())
rspPDU = PDU['pMod'].apiMessage.getPDU(rspMsg)
# Match response to request
if PDU['pMod'].apiPDU.getRequestID(PDU['reqPDU']) == PDU['pMod'].apiPDU.getRequestID(rspPDU):
errorStatus = PDU['pMod'].apiPDU.getErrorStatus(rspPDU)
if not (errorStatus and errorStatus != 2):
PDUarr = []
varBindTable = PDU['pMod'].apiPDU.getVarBindTable(PDU['reqPDU'], rspPDU)
for tableRow in varBindTable:
for oid, val in tableRow:
print('from: %s, %s = %s' % (transportAddress, oid.prettyPrint(), val.prettyPrint()))
if str(oid.prettyPrint()) not in Device.scan.params['MIBs']:
for mibOID in PDU['MIBs']:
if str(oid.prettyPrint()).find(mibOID) != -1 and mibOID not in Device.scan.devices[ip].MIBs:
Device.scan.devices[ip].MIBs.append(mibOID)
for tree in PDU['OIDs']:
if str(oid.prettyPrint()).find(tree) != -1 and str(oid.prettyPrint()) not in Device.scan.devices[ip].OIDs:
Device.scan.devices[ip].OIDs[str(oid.prettyPrint())] = val.prettyPrint()[:-1][2:] if val.prettyPrint().startswith("b'") and val.prettyPrint().endswith("'") else val.prettyPrint()
PDUarr.append((str(oid.prettyPrint()), PDU['pMod'].null))
# Stop on EOM
for oid, val in varBindTable[-1]:
if not isinstance(val, PDU['pMod'].Null):
break
else:
Progress.networks[ip]['Done'] = True
print("IP-------- " + ip)
Progress.progress.append(1)
Device.transportDispatcher.jobFinished(1)
continue
# Generate request for next row
print(PDUarr)
if PDUarr != []:
PDU['pMod'].apiPDU.setVarBinds(PDU['reqPDU'], PDUarr)
PDU['pMod'].apiPDU.setRequestID(PDU['reqPDU'], PDU['pMod'].getNextRequestID())
Device.transportDispatcher.sendMessage(
encoder.encode(PDU['reqMsg']), transportDomain, transportAddress
)
Progress.networks[ip]['Time'] = time.time()
else:
Progress.networks[ip]['Done'] = True
print("IP-------- " + ip)
Progress.progress.append(1)
Device.transportDispatcher.jobFinished(1)
continue
And this is the error i receive:
37998-octet short
Traceback (most recent call last):
File "C:\device.py", line 137, in cbFun_Device
File "C:\Python34\lib\site-packages\pyasn1\codec\ber\decoder.py", line 706, in __call__
pyasn1.error.SubstrateUnderrunError: 37998-octet short
And sometimes this error too:
pyasn1.error.PyAsn1Error: Empty substrate
but all errors happen on this line:
rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec = PDU['pMod'].Message())
What is going on?

Getting stats from ryu controller

I'm trying obtain stats in ryu (with python).
But when I run mi code only configures the switch, and doesn't make anything else. I've just started with python progamming and I can't find the mistake.
class SimpleSwitch(app_manager.RyuApp):
def __init__(self, *args, **kwargs):
super(SimpleSwitch, self).__init__(*args, **kwargs)
self.mac_to_port = {}
def send_desc_stats_requests(self, datapath):
ofp_parser = datapath.ofproto_parser
req = ofp_parser.OFPDescStatsRequest(datapath,0)
datapath.send_msg(req)
#set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER)
def desc_stats_reply_handler(self,body):
ofp = msg.datapath.ofproto
body = ev.msg.body
self.logger.info('OFPDescStatsReply received: '
'mfr_desc=%d hw_desc=%s sw_desc=%s '
'serial_num=%s dp_desc=%s ',
body.mfr_desc, body.hw_desc, body.sw_desc,
body.serial_num, body.dp_desc)
def add_flow(self, datapath, in_port, dst, actions):
ofproto = datapath.ofproto
match = datapath.ofproto_parser.OFPMatch(
in_port=in_port, dl_dst=haddr_to_bin(dst))
mod = datapath.ofproto_parser.OFPFlowMod(
datapath=datapath, match=match, cookie=0,
command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
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
pkt = packet.Packet(msg.data)
eth = pkt.get_protocol(ethernet.ethernet)
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, msg.in_port)
self.desc_stats_reply_handler(self,body)
# learn a mac address to avoid FLOOD next time.
self.mac_to_port[dpid][src] = msg.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 = [datapath.ofproto_parser.OFPActionOutput(out_port)]
# install a flow to avoid packet_in next time
if out_port != ofproto.OFPP_FLOOD:
self.add_flow(datapath, msg.in_port, dst, actions)
out = datapath.ofproto_parser.OFPPacketOut(
datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
actions=actions)
datapath.send_msg(out)
#set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
def multipart_reply_handler(self, ev):
msg = ev.msg
reason = msg.reason
port_no = msg.desc.port_no
ofproto = msg.datapath.ofproto
if reason == ofproto.OFPPR_ADD:
self.logger.info("port added %s", port_no)
elif reason == ofproto.OFPPR_DELETE:
self.logger.info("port deleted %s", port_no)
elif reason == ofproto.OFPPR_MODIFY:
self.logger.info("port modified %s", port_no)
else:
self.logger.info("Illeagal port state %s %s", port_no, reason)
Thanks.
In your code, you have created a method named send_desc_stats_requests(self, datapath) to request for the stats. That method is requesting stats from the switch.
Instead of calling self.desc_stats_reply_handler(self,body) in packet in handler, you should call self.desc_stats_request(datapath). So, here you should request for stats from switch, so that switch will reply the stats description and when ryu controller will receive that reply message, controller will run self.desc_stats_reply_handler(self,body) as it has
#set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER)
In the short, call self.desc_stats_request(datapath) instead of calling reply_handler
Vishlesh Gave a good answer.
But there are some error present in your code.
def desc_stats_reply_handler(self,ev):
body = ev.msg.body
self.logger.info('OFPDescStatsReply received: '
'mfr_desc=%d hw_desc=%s sw_desc=%s '
'serial_num=%s dp_desc=%s ',
body.mfr_desc, body.hw_desc, body.sw_desc,
body.serial_num, body.dp_desc)

Categories