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

Reply via email to