I just realized that I was doing a double htonl on attrs['speed'] in my
set_port method in utils.py. There's some funning looking logic there as
my htonl was generating a -ve value when the speed was 1000 and SWIG was
generating an error as it wasn't of type unit32 :-(
Corrected patch attached.
Glen
Glen Gibb wrote:
Hi all,
Attached are the diffs to enable me to send port mods from python.
Feel free to integrate the diff and let me know if you have any
comments/questions.
Oh, and to actually send a port mod I just do this from my app:
self.ctxt.send_port_mod(dp, set_port(port))
where port is a dictionary identical to that returned in the stats in
a dp_join event.
Glen
------------------------------------------------------------------------
_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org
diff --git a/src/nox/apps/pyrt/context.i b/src/nox/apps/pyrt/context.i
index b02a3b8..54d0f4e 100644
--- a/src/nox/apps/pyrt/context.i
+++ b/src/nox/apps/pyrt/context.i
@@ -80,6 +80,9 @@ public:
void send_port_stats_request(uint64_t datapath_id);
void send_aggregate_stats_request(uint64_t datapath_ids, const
struct ofp_match& match, uint8_t table_id);
+
+ void send_port_mod(uint64_t datapath_id,
+ const ofp_phy_port& port);
private:
PyContext();
diff --git a/src/nox/apps/pyrt/pycontext.cc b/src/nox/apps/pyrt/pycontext.cc
index 87d8111..7c5dc2f 100644
--- a/src/nox/apps/pyrt/pycontext.cc
+++ b/src/nox/apps/pyrt/pycontext.cc
@@ -234,6 +234,30 @@ PyContext::send_stats_request(uint64_t datapath_id, ofp_stats_types type, const
}
}
+void
+PyContext::send_port_mod(uint64_t datapath_id,
+ const ofp_phy_port& port) {
+ ofp_port_mod* opm = NULL;
+ size_t size = sizeof *opm;
+ boost::shared_array<uint8_t> raw_of(new uint8_t[size]);
+ opm = (ofp_port_mod*) raw_of.get();
+
+ opm->header.version = OFP_VERSION;
+ opm->header.type = OFPT_PORT_MOD;
+ opm->header.length = htons(size);
+ opm->header.xid = htonl(0);
+
+ ::memcpy(&opm->desc, &port, sizeof port);
+
+ int error = c->send_openflow_command(datapathid::from_host(datapath_id),
+ &opm->header, false);
+ if (error == EAGAIN) {
+ vlog().log(vlog().get_module_val("pyrt"), Vlog::LEVEL_ERR,
+ "should queue port_mod");
+ }
+}
+
+
bool
PyContext::unregister_handler(uint32_t rule_id) {
return c->unregister_handler(rule_id);
diff --git a/src/nox/apps/pyrt/pycontext.hh b/src/nox/apps/pyrt/pycontext.hh
index a18158d..186b16e 100644
--- a/src/nox/apps/pyrt/pycontext.hh
+++ b/src/nox/apps/pyrt/pycontext.hh
@@ -113,6 +113,9 @@ public:
void send_aggregate_stats_request(uint64_t datapath_ids, const
struct ofp_match& match, uint8_t table_id);
+ void send_port_mod(uint64_t datapath_id,
+ const ofp_phy_port& port);
+
/* C++ context */
const container::Context* ctxt;
diff --git a/src/nox/lib/openflow.i b/src/nox/lib/openflow.i
index 3dd2286..3b47d82 100644
--- a/src/nox/lib/openflow.i
+++ b/src/nox/lib/openflow.i
@@ -24,9 +24,19 @@
using namespace vigil;
%}
+%include "cstring.i"
%include "common-defs.i"
%include "openflow.h"
+%extend ofp_phy_port {
+ void set_hw_addr(uint8_t *addr) {
+ memcpy($self->hw_addr, addr, ethernetaddr::LEN);
+ }
+ void set_name(const char *name) {
+ memcpy($self->name, name, OFP_MAX_PORT_NAME_LEN);
+ }
+};
+
%extend ofp_match {
void set_dl_src(uint8_t *addr) {
memcpy($self->dl_src, addr, ethernetaddr::LEN);
diff --git a/src/nox/lib/util.py b/src/nox/lib/util.py
index 25f49c5..ed42960 100644
--- a/src/nox/lib/util.py
+++ b/src/nox/lib/util.py
@@ -17,7 +17,7 @@
import core
import array
-from socket import htons
+from socket import htons, htonl
import nox.lib.openflow as openflow
@@ -285,6 +285,53 @@ def set_match(attrs):
m.wildcards = htons(wildcards)
return m
+def set_port(attrs):
+ p = openflow.ofp_phy_port()
+
+ print attrs
+ if attrs.has_key('port_no'):
+ p.port_no = htons(attrs['port_no'])
+ else:
+ print 'undefined port_no attribute type in attrs', attrs
+ return None
+
+ if attrs.has_key('hw_addr'):
+ v = convert_to_eaddr(attrs['hw_addr'])
+ if v == None:
+ print 'invalid ethernet addr'
+ return None
+ p.set_hw_addr(v.octet)
+ else:
+ print 'undefined hw_addr attribute type in attrs', attrs
+ return None
+
+ if attrs.has_key('name'):
+ p.set_name(attrs['name'])
+ else:
+ print 'undefined name attribute type in attrs', attrs
+ return None
+
+ if attrs.has_key('flags'):
+ p.flags = htonl(attrs['flags'])
+ else:
+ p.flags = 0
+
+ if attrs.has_key('speed'):
+ speed = htonl(attrs['speed'])
+ if speed < 0:
+ speed += 2**32;
+ p.speed = speed
+ else:
+ print 'undefined speed attribute type in attrs', attrs
+ return None
+
+ if attrs.has_key('features'):
+ p.features = htonl(attrs['features'])
+ else:
+ p.features = 0
+
+ return p
+
def extract_flow(ethernet):
"""
Extracts and returns flow attributes from the given 'ethernet' packet.
_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org