Re: [nox-dev] Port mod python example?
Glen, what are you looking to modify? Currently, you are only able to set the port flags over OpenFlow and the only flag is one to indicate whether the port should be included in flood actions. We're looking to include actions such as disabling ports, but that's not in there yet. --Justin On Aug 9, 2008, at 12:36 PM, Martin Casado wrote: I'm not sure port mod is supported in the OF reference implementation. Justin/Ben? On Aug 8, 2008, at 4:42 PM, Glen Gibb wrote: Hi all, Is there an example available that sends port mod messages to a switch? I'm currently looking for examples but can't find one. Thanks, Glen ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org
Re: [nox-dev] Port mod python example?
I'm looking to set the flood flag so that when I have loops in my topology I don't end up looping packets forever. I've actually written most of the code -- I'm just having trouble right now copying the name into the name field from Python. Actually, do I need to send the name back to the OF switch or will it work without setting a name? Here's the one snippet of code I haven't yet gotten working. In openflow.i I have: %extend ofp_phy_port { void set_hw_addr(uint8_t *addr) { memcpy($self-hw_addr, addr, ethernetaddr::LEN); } void set_name(uint8_t *name) { memcpy($self-name, name, OFP_MAX_PORT_NAME_LEN); } }; (I'm basically trying to copy what you had in that file for ofp_match.) The set_hw_addr works perfectly, the set_name fails because I haven't yet managed to convert my string to a uint8_t array. Is there an easy way to pass in a python string to set_name and copy from the Python string to the name field? Glen Justin Pettit wrote: Glen, what are you looking to modify? Currently, you are only able to set the port flags over OpenFlow and the only flag is one to indicate whether the port should be included in flood actions. We're looking to include actions such as disabling ports, but that's not in there yet. --Justin On Aug 9, 2008, at 12:36 PM, Martin Casado wrote: I'm not sure port mod is supported in the OF reference implementation. Justin/Ben? On Aug 8, 2008, at 4:42 PM, Glen Gibb wrote: Hi all, Is there an example available that sends port mod messages to a switch? I'm currently looking for examples but can't find one. Thanks, Glen ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org
Re: [nox-dev] Port mod from python -- patch
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_arrayuint8_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: +
Re: [nox-dev] Port mod python example?
Here's the definition for the flags from openflow.h: /* Flags to indicate behavior of the physical port */ enum ofp_port_flags { OFPPFL_NO_FLOOD = 1 0, /* Do not include this port when flooding */ }; So by default, the flags should be off. If you do not want to include them when flooding, then they should be enabled. I think things are working properly, but maybe I'm misunderstanding something here... --Justin On Aug 9, 2008, at 1:22 PM, Glen Gibb wrote: Hi Justin, It seems that the OpenFlow reference implementation is incorrectly reporting the flags field for ofp_phy_port in the features reply (or I'm mis-interpreting what this should be). Looking at a packet capture for the features reply (see attached packet) it always reports 0 in the flags -- I would expect this to be 1 since by default all ports participate in flooding. Glen Glen Gibb wrote: I'm looking to set the flood flag so that when I have loops in my topology I don't end up looping packets forever. I've actually written most of the code -- I'm just having trouble right now copying the name into the name field from Python. Actually, do I need to send the name back to the OF switch or will it work without setting a name? Here's the one snippet of code I haven't yet gotten working. In openflow.i I have: %extend ofp_phy_port { void set_hw_addr(uint8_t *addr) { memcpy($self-hw_addr, addr, ethernetaddr::LEN); } void set_name(uint8_t *name) { memcpy($self-name, name, OFP_MAX_PORT_NAME_LEN); } }; (I'm basically trying to copy what you had in that file for ofp_match.) The set_hw_addr works perfectly, the set_name fails because I haven't yet managed to convert my string to a uint8_t array. Is there an easy way to pass in a python string to set_name and copy from the Python string to the name field? Glen Justin Pettit wrote: Glen, what are you looking to modify? Currently, you are only able to set the port flags over OpenFlow and the only flag is one to indicate whether the port should be included in flood actions. We're looking to include actions such as disabling ports, but that's not in there yet. --Justin On Aug 9, 2008, at 12:36 PM, Martin Casado wrote: I'm not sure port mod is supported in the OF reference implementation. Justin/Ben? On Aug 8, 2008, at 4:42 PM, Glen Gibb wrote: Hi all, Is there an example available that sends port mod messages to a switch? I'm currently looking for examples but can't find one. Thanks, Glen ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org features_reply.pcap ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org
Re: [nox-dev] Core dump when registering non-existent callback in post_callback
Great, thanks Glen. I'll submit a bug. I accidentally tried to register a non-existent callback with post_callback and Nox dumped core: terminate called after throwing an instance of 'std::runtime_error' what(): cannot install the Python component: Traceback (most recent call last): File ./nox/apps/spanning_tree/spanning_tree.py, line 74, in install self.post_callback(1, self.process_links) AttributeError: Spanning_Tree instance has no attribute 'process_links' Caught signal 6. 0xb7d7da0d 32 (vigil::fault_handler(int)+0x3d) 0xb7ee9400 2901005704 (__kernel_sigreturn+0x0) 0xb7af0fb8 296 (abort+0x188) 0xb7d0e8f8 64 (__gnu_cxx::__verbose_terminate_handler()+0x158) 0xb7d0c7d5 0xb7d0c812 0xb7d0c835 0xb7d0c168 96 (__cxa_call_unexpected+0x48) 0x08093149 112 (vigil::Kernel::change(vigil::Component_context*, vigil::Component_state)+0x339) 0x080932fb 96 (vigil::Kernel::install(vigil::Component_context*)+0x13b) 0x0807ef30 64 (vigil::Deployer::deploy(vigil::Kernel*, std::string const)+0xa0) 0x0809493a 496 (vigil::Kernel::install(std::string const)+0x12a) 0x080743df 0x0807dad1 80 (boost::detail::function::void_function_obj_invoker0boost::_bi::bind_tvoid, void (*)(vigil::Kernel*, std::__debug::liststd::pairstd::string, std::__debug::liststd::string, std::allocatorstd::string , std::allocatorstd::pairstd::string, std::__debug::liststd::string, std::allocatorstd::string const, std::__debug::vectorstd::string, std::allocatorstd::string , bool), boost::_bi::list4boost::_bi::valuevigil::Kernel*, boost::_bi::valuestd::__debug::liststd::pairstd::string, std::__debug::liststd::string, std::allocatorstd::string , std::allocatorstd::pairstd::string, std::__debug::liststd::string, std::allocatorstd::string , boost::_bi::valuestd::__debug::vectorstd::string, std::allocatorstd::string , boost::_bi::valuebool , void::invoke(boost::detail::function::function_buffer)+0x41) 0xb7da36cc 80 (boost::function0void, std::allocatorvoid ::operator()() const+0x2c) 0xb7d9cf03 0xb76e04b0 Aborted (core dumped) Glen ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org ___ nox-dev mailing list nox-dev@noxrepo.org http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org