From 9bcb4e147bf1dc4ad63582f93ed7b53216057cc9 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Thu, 2 Jul 2015 14:52:46 +0200 Subject: [PATCH 01/19] Add controller from rest plugin implemented --- .../management/plugins/rest/put-controllers.h | 5 ++ src/xdpd/management/plugins/rest/rest.cc | 7 ++ .../management/plugins/rest/sw-controllers.cc | 83 +++++++++++++++++++ src/xdpd/management/plugins/rest/xcli | 53 +++++++++++- 4 files changed, 147 insertions(+), 1 deletion(-) diff --git a/src/xdpd/management/plugins/rest/put-controllers.h b/src/xdpd/management/plugins/rest/put-controllers.h index 41729fa6..baa1647e 100644 --- a/src/xdpd/management/plugins/rest/put-controllers.h +++ b/src/xdpd/management/plugins/rest/put-controllers.h @@ -17,6 +17,11 @@ namespace put{ * Create a vlink */ void create_vlink(const http::server::request &, http::server::reply &, boost::cmatch&); + + /* + * Add a new controller to the LSI + */ + void add_ctl(const http::server::request &, http::server::reply &, boost::cmatch&); } //namespace put } //namespace controllers diff --git a/src/xdpd/management/plugins/rest/rest.cc b/src/xdpd/management/plugins/rest/rest.cc index ef994a03..59c67447 100644 --- a/src/xdpd/management/plugins/rest/rest.cc +++ b/src/xdpd/management/plugins/rest/rest.cc @@ -99,6 +99,13 @@ static void srvthread (){ handler.register_post_path("/mgmt/create/lsi", boost::bind(controllers::put::create_lsi, _1, _2, _3)); handler.register_put_path("/mgmt/create/vlink/(\\w+)/(\\w+)", boost::bind(controllers::put::create_vlink, _1, _2, _3)); + // + // CONTROLLERS + // + handler.register_put_path("/mgmt/add/controller/(\\w+)", boost::bind(controllers::put::add_ctl, _1, _2, _3)); + // delete ctl + // list ctls + // //DELETE // diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index d75b537f..6809da4d 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -358,6 +358,89 @@ void create_lsi(const http::server::request &req, http::server::reply &rep, boos //There is no need to return anything } + +void add_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ + + //call switch_manager to add a new controller to the LSI + // get IP & port from the req parameter (json?) + // check IP & port (if there is already a controller there, send error message) + std::stringstream ss; + std::string proto, ip, port; + enum rofl::csocket::socket_type_t socket_type; + rofl::cparams socket_params; + + //Perform security checks + if(!authorised(req,rep)) return; + + std::string lsi_name = std::string(grps[1]); + + //Check if LSI exists; + if(!switch_manager::exists_by_name(lsi_name)){ + //Throw 404 + std::stringstream ss; + ss<<"Invalid lsi '"< Date: Tue, 7 Jul 2015 10:18:38 +0200 Subject: [PATCH 02/19] Basic remove controller functionality for REST interface --- .../plugins/rest/delete-controllers.h | 1 + src/xdpd/management/plugins/rest/rest.cc | 2 +- .../management/plugins/rest/sw-controllers.cc | 43 +++++++++++++++++++ src/xdpd/management/plugins/rest/xcli | 9 ++-- src/xdpd/management/switch_manager.cc | 4 +- src/xdpd/management/switch_manager.h | 3 +- src/xdpd/openflow/openflow_switch.cc | 10 ++++- src/xdpd/openflow/openflow_switch.h | 2 +- 8 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/xdpd/management/plugins/rest/delete-controllers.h b/src/xdpd/management/plugins/rest/delete-controllers.h index 623a4029..e79b2d01 100644 --- a/src/xdpd/management/plugins/rest/delete-controllers.h +++ b/src/xdpd/management/plugins/rest/delete-controllers.h @@ -12,6 +12,7 @@ namespace delete_{ * Destroy an LSI */ void destroy_switch(const http::server::request &, http::server::reply &, boost::cmatch&); + void rem_ctl(const http::server::request &, http::server::reply &, boost::cmatch&); } //namespace delete_ } //namespace controllers diff --git a/src/xdpd/management/plugins/rest/rest.cc b/src/xdpd/management/plugins/rest/rest.cc index 59c67447..6318d23e 100644 --- a/src/xdpd/management/plugins/rest/rest.cc +++ b/src/xdpd/management/plugins/rest/rest.cc @@ -103,7 +103,7 @@ static void srvthread (){ // CONTROLLERS // handler.register_put_path("/mgmt/add/controller/(\\w+)", boost::bind(controllers::put::add_ctl, _1, _2, _3)); - // delete ctl + handler.register_delete_path("/mgmt/remove/controller/(\\w+)/(\\w+)", boost::bind(controllers::delete_::rem_ctl, _1, _2, _3)); // list ctls // diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 6809da4d..f6511a3b 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -478,6 +478,49 @@ void destroy_switch(const http::server::request &req, http::server::reply &rep, } } +void rem_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ + + std::stringstream ss; + std::string lsi_name; + std::string ctlid_str; + uint64_t dpid, ctl_id; + + //Perform security checks + if(!authorised(req,rep)) return; + + lsi_name = std::string(grps[1]); + ctlid_str = std::string(grps[2]); + + //Check if LSI exists; + if(!switch_manager::exists_by_name(lsi_name)){ + //Throw 404 + std::stringstream ss; + ss<<"Invalid lsi '"<" elif "remove" in command: data = "" if "controller" in command: - return rest(socket. compose_url(stripped), data, "PUT") + return rest(socket, compose_url(stripped), data, "DELETE") else: - return "Usage: exec remove controller ..." + return "Usage: exec remove controller " else: return rest(socket, compose_url(stripped), "", "POST") @@ -529,7 +530,7 @@ class InteractivePrompt(cmd.Cmd): print_less(result) def complete_exec(self, text, line, start_index, end_index): - exec_cmds = ["port", "attach", "detach", "create", "destroy", "add", "remove"] + exec_cmds = ["port", "attach", "detach", "create", "destroy", "add controller", "remove controller"] for cmd in exec_cmds: if cmd in line: diff --git a/src/xdpd/management/switch_manager.cc b/src/xdpd/management/switch_manager.cc index 4b4d081a..376047ec 100644 --- a/src/xdpd/management/switch_manager.cc +++ b/src/xdpd/management/switch_manager.cc @@ -407,7 +407,7 @@ switch_manager::rpc_connect_to_ctl(uint64_t dpid, enum rofl::csocket::socket_typ void -switch_manager::rpc_disconnect_from_ctl(uint64_t dpid, enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params){ +switch_manager::rpc_disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid){ pthread_rwlock_wrlock(&switch_manager::rwlock); @@ -418,7 +418,7 @@ switch_manager::rpc_disconnect_from_ctl(uint64_t dpid, enum rofl::csocket::socke //Get switch instance openflow_switch* dp = switch_manager::switchs[dpid]; - dp->rpc_disconnect_from_ctl(socket_type, socket_params); + dp->rpc_disconnect_from_ctl(ctlid); pthread_rwlock_unlock(&switch_manager::rwlock); } diff --git a/src/xdpd/management/switch_manager.h b/src/xdpd/management/switch_manager.h index d0437b1e..9a7c246d 100644 --- a/src/xdpd/management/switch_manager.h +++ b/src/xdpd/management/switch_manager.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -172,7 +173,7 @@ class switch_manager { /** * disconnect from from controller */ - static void rpc_disconnect_from_ctl(uint64_t dpid, enum rofl::csocket::socket_type_t socket_type, rofl::cparams const& socket_params); + static void rpc_disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid ); // // Other configuration parameters diff --git a/src/xdpd/openflow/openflow_switch.cc b/src/xdpd/openflow/openflow_switch.cc index 2840dc59..75cc774e 100644 --- a/src/xdpd/openflow/openflow_switch.cc +++ b/src/xdpd/openflow/openflow_switch.cc @@ -36,7 +36,13 @@ void openflow_switch::rpc_connect_to_ctl(enum rofl::csocket::socket_type_t socke endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap).connect(rofl::cauxid(0), socket_type, socket_params); } -void openflow_switch::rpc_disconnect_from_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params){ - //endpoint->rpc_disconnect_from_ctl(socket_type, socket_params); +void openflow_switch::rpc_disconnect_from_ctl(rofl::cctlid ctlid){ + // TODO check for a valid ID + //if (endpoint->has_ctl(ctlid)){ + endpoint->drop_ctl(ctlid); + //} + //else { + // throw eOfSmNotFound; + //} } diff --git a/src/xdpd/openflow/openflow_switch.h b/src/xdpd/openflow/openflow_switch.h index dfb43364..716cbb9c 100644 --- a/src/xdpd/openflow/openflow_switch.h +++ b/src/xdpd/openflow/openflow_switch.h @@ -98,7 +98,7 @@ class openflow_switch { */ virtual void rpc_connect_to_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params); - virtual void rpc_disconnect_from_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params); + virtual void rpc_disconnect_from_ctl(rofl::cctlid ctlid); protected: /* From 88efc5d99e149a050e2dc7b3971a9dcbc34c3caa Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Tue, 7 Jul 2015 16:56:37 +0200 Subject: [PATCH 03/19] implementation of list in xcli and in endpoint. It is still not glued in the REST plugin --- .../management/plugins/rest/get-controllers.h | 6 ++++++ src/xdpd/management/plugins/rest/rest.cc | 3 ++- .../management/plugins/rest/sw-controllers.cc | 8 ++++++++ src/xdpd/management/plugins/rest/xcli | 2 ++ src/xdpd/management/switch_manager.cc | 16 ++++++++++++++++ src/xdpd/management/switch_manager.h | 7 ++++++- src/xdpd/openflow/openflow_switch.cc | 3 +++ src/xdpd/openflow/openflow_switch.h | 2 ++ 8 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/xdpd/management/plugins/rest/get-controllers.h b/src/xdpd/management/plugins/rest/get-controllers.h index e990b979..5d629a6f 100644 --- a/src/xdpd/management/plugins/rest/get-controllers.h +++ b/src/xdpd/management/plugins/rest/get-controllers.h @@ -35,6 +35,12 @@ namespace get{ void list_ports(const http::server::request &, http::server::reply &, boost::cmatch&); void port_detail(const http::server::request &, http::server::reply &, boost::cmatch&); + /** + * Controllers + */ + void list_ctls(const http::server::request &, http::server::reply &, boost::cmatch&); + void show_ctl(const http::server::request &, http::server::reply &, boost::cmatch&); + } //namespace get } //namespace controllers } //namespace xdpd diff --git a/src/xdpd/management/plugins/rest/rest.cc b/src/xdpd/management/plugins/rest/rest.cc index 6318d23e..f3661fe1 100644 --- a/src/xdpd/management/plugins/rest/rest.cc +++ b/src/xdpd/management/plugins/rest/rest.cc @@ -104,7 +104,8 @@ static void srvthread (){ // handler.register_put_path("/mgmt/add/controller/(\\w+)", boost::bind(controllers::put::add_ctl, _1, _2, _3)); handler.register_delete_path("/mgmt/remove/controller/(\\w+)/(\\w+)", boost::bind(controllers::delete_::rem_ctl, _1, _2, _3)); - // list ctls + handler.register_get_path("/info/lsi/(\\w+)/ctls", boost::bind(controllers::get::list_ctls, _1, _2, _3)); + handler.register_get_path("/info/lsi/(\\w+)/ctl/(\\w+)", boost::bind(controllers::get::show_ctl, _1, _2, _3)); // //DELETE diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index f6511a3b..7284731a 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -236,6 +236,14 @@ void lsi_groups(const http::server::request &req, rep.content = json_spirit::write(wrap, true); } +void list_ctls(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ + fprintf(stderr,"LIST CONTROLLERS CALLED\n"); +} + +void show_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ + fprintf(stderr,"SHOW CONTROLLER CALLED\n"); +} + } //namespace get diff --git a/src/xdpd/management/plugins/rest/xcli b/src/xdpd/management/plugins/rest/xcli index c83aafb7..cbcc1f58 100755 --- a/src/xdpd/management/plugins/rest/xcli +++ b/src/xdpd/management/plugins/rest/xcli @@ -42,6 +42,8 @@ def list_show_commands(): string+= ' show lsi \t\t\t - Show LSI information\n' string+= ' show lsi table flows - Show LSI table flows\n' string+= ' show lsi group-table\t - List LSI group-table entries\n' + string+= ' show lsi ctls\t - List IDs of LSI\'s Controllers\n' + string+= ' show lsi ctl \t - Show Controller information\n' string+= ' show ports\t\t\t\t - List the available ports in the platform\n' string+= ' show port \t\t - Show port information\n' return string diff --git a/src/xdpd/management/switch_manager.cc b/src/xdpd/management/switch_manager.cc index 376047ec..54082f98 100644 --- a/src/xdpd/management/switch_manager.cc +++ b/src/xdpd/management/switch_manager.cc @@ -422,6 +422,22 @@ switch_manager::rpc_disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid){ pthread_rwlock_unlock(&switch_manager::rwlock); } +void +switch_manager::rpc_list_ctls(uint64_t dpid, std::list list){ + pthread_rwlock_wrlock(&switch_manager::rwlock); + + if (switch_manager::switchs.find(dpid) == switch_manager::switchs.end()){ + pthread_rwlock_unlock(&switch_manager::rwlock); + throw eOfSmDoesNotExist(); + } + + //Get switch instance + openflow_switch* dp = switch_manager::switchs[dpid]; + dp->rpc_list_ctls(list); + pthread_rwlock_unlock(&switch_manager::rwlock); + +} + // // Other configuration parameters diff --git a/src/xdpd/management/switch_manager.h b/src/xdpd/management/switch_manager.h index 9a7c246d..43cf6f96 100644 --- a/src/xdpd/management/switch_manager.h +++ b/src/xdpd/management/switch_manager.h @@ -173,7 +173,12 @@ class switch_manager { /** * disconnect from from controller */ - static void rpc_disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid ); + static void rpc_disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid); + + /** + * list the available controllers ids + */ + static void rpc_list_ctls(uint64_t dpid, std::list list); // // Other configuration parameters diff --git a/src/xdpd/openflow/openflow_switch.cc b/src/xdpd/openflow/openflow_switch.cc index 75cc774e..06a42beb 100644 --- a/src/xdpd/openflow/openflow_switch.cc +++ b/src/xdpd/openflow/openflow_switch.cc @@ -46,3 +46,6 @@ void openflow_switch::rpc_disconnect_from_ctl(rofl::cctlid ctlid){ //} } +void openflow_switch::rpc_list_ctls(std::list ctls_list){ + endpoint->list_ctls(ctls_list); +} diff --git a/src/xdpd/openflow/openflow_switch.h b/src/xdpd/openflow/openflow_switch.h index 716cbb9c..9d860eb9 100644 --- a/src/xdpd/openflow/openflow_switch.h +++ b/src/xdpd/openflow/openflow_switch.h @@ -100,6 +100,8 @@ class openflow_switch { virtual void rpc_disconnect_from_ctl(rofl::cctlid ctlid); + virtual void rpc_list_ctls(std::list); + protected: /* * Pure virtual method that must be implemented by derived classes From 978ca724d2c03a4dc408e1522b7d13f49b5fcc02 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Wed, 8 Jul 2015 16:12:43 +0200 Subject: [PATCH 04/19] Implemented list IDs from LSI --- .../management/plugins/rest/sw-controllers.cc | 90 ++++++++++++++++++- src/xdpd/management/switch_manager.cc | 2 +- src/xdpd/management/switch_manager.h | 2 +- src/xdpd/openflow/openflow_switch.cc | 5 +- src/xdpd/openflow/openflow_switch.h | 2 +- 5 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 7284731a..8e23c969 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -238,10 +238,90 @@ void lsi_groups(const http::server::request &req, void list_ctls(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ fprintf(stderr,"LIST CONTROLLERS CALLED\n"); + std::stringstream ss; + std::string lsi_name; + uint64_t dpid; + std::list list; + json_spirit::Object table; + + //Perform security checks + if(!authorised(req,rep)) return; + + lsi_name = std::string(grps[1]); + + fprintf(stderr,"listing controllers from lsi %s\n", lsi_name.c_str()); + + // Get dpid + try{ + dpid = switch_manager::get_switch_dpid(lsi_name); + }catch(...){ + ss<<"Unable to find a dpid for lsi " << lsi_name; + rep.content = ss.str(); + rep.status = http::server::reply::bad_request; + return; + } + + fprintf(stderr, "dpid %lu\n", dpid); + + try{ + ss<<"Listing controllers from: " << lsi_name; + switch_manager::rpc_list_ctls(dpid, &list); + }catch(...){ + fprintf(stderr, "ERROR switch_manager::rpc_list_ctls\n"); + ss<<"Unable to get list of ctls from lsi '"< list_str; + for(std::list::iterator it = list.begin(); it != list.end(); it++){ + fprintf(stderr,"found ctl-ID %lu\n", it->get_ctlid()); + std::stringstream ss_tmp; + ss_tmp << it->get_ctlid(); + list_str.push_back(ss_tmp.str()); + } + + json_spirit::Value ids_(list_str.begin(), list_str.end()); + table.push_back(json_spirit::Pair("ids", ids_)); + rep.content = json_spirit::write(table, true); } void show_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ fprintf(stderr,"SHOW CONTROLLER CALLED\n"); + std::stringstream ss; + std::string lsi_name, ctl_id; + uint64_t dpid; + + //Perform security checks + if(!authorised(req,rep)) return; + + lsi_name = std::string(grps[1]); + ctl_id = std::string(grps[2]); + + fprintf(stderr,"showing controller from lsi %s, id %s\n", lsi_name.c_str(), ctl_id.c_str()); + + // Get dpid + try{ + dpid = switch_manager::get_switch_dpid(lsi_name); + }catch(...){ + ss<<"Unable to find a dpid for lsi " << lsi_name; + rep.content = ss.str(); + rep.status = http::server::reply::bad_request; + return; + } + + fprintf(stderr, "dpid %lu\n", dpid); +#if 0 + try{ + ss<<"Listing controller info: " << lsi_name; + switch_manager::rpc_show_ctl(dpid, id, info); + }catch(...){ + + } + //Return data +#endif } } //namespace get @@ -376,6 +456,7 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: std::string proto, ip, port; enum rofl::csocket::socket_type_t socket_type; rofl::cparams socket_params; + //json_spirit::Object table; //Perform security checks if(!authorised(req,rep)) return; @@ -392,9 +473,8 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: return; } - // Get dpid + // Get dpid TODO check for failure uint64_t dpid = switch_manager::get_switch_dpid(lsi_name); - //fprintf(stderr,"found dpid:%lu\n", dpid); // Parse data (protocol, IP & port) try{ @@ -414,7 +494,6 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: }catch(...){ //Something went wrong - std::stringstream ss; ss<<"Unable to parse arguments for add controller"; rep.content = ss.str(); rep.status = http::server::reply::bad_request; @@ -437,16 +516,19 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: try{ ss<<"Adding Controller: " << lsi_name << " : " << proto; + //uint64_t id = switch_manager::rpc_connect_to_ctl(dpid, socket_type, socket_params); switch_manager::rpc_connect_to_ctl(dpid, socket_type, socket_params); }catch(...){ //Something went wrong - std::stringstream ss; ss<<"Unable to add controller to lsi '"< list){ +switch_manager::rpc_list_ctls(uint64_t dpid, std::list* list){ pthread_rwlock_wrlock(&switch_manager::rwlock); if (switch_manager::switchs.find(dpid) == switch_manager::switchs.end()){ diff --git a/src/xdpd/management/switch_manager.h b/src/xdpd/management/switch_manager.h index 43cf6f96..f39db54a 100644 --- a/src/xdpd/management/switch_manager.h +++ b/src/xdpd/management/switch_manager.h @@ -178,7 +178,7 @@ class switch_manager { /** * list the available controllers ids */ - static void rpc_list_ctls(uint64_t dpid, std::list list); + static void rpc_list_ctls(uint64_t dpid, std::list *list); // // Other configuration parameters diff --git a/src/xdpd/openflow/openflow_switch.cc b/src/xdpd/openflow/openflow_switch.cc index 06a42beb..215d5ed8 100644 --- a/src/xdpd/openflow/openflow_switch.cc +++ b/src/xdpd/openflow/openflow_switch.cc @@ -33,7 +33,10 @@ rofl_result_t openflow_switch::notify_port_status_changed(const switch_port_t* p void openflow_switch::rpc_connect_to_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params){ rofl::openflow::cofhello_elem_versionbitmap versionbitmap; versionbitmap.add_ofp_version(version); + //rofl::crofctl* ctl = endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap).connect(rofl::cauxid(0), socket_type, socket_params); endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap).connect(rofl::cauxid(0), socket_type, socket_params); + + //return id; } void openflow_switch::rpc_disconnect_from_ctl(rofl::cctlid ctlid){ @@ -46,6 +49,6 @@ void openflow_switch::rpc_disconnect_from_ctl(rofl::cctlid ctlid){ //} } -void openflow_switch::rpc_list_ctls(std::list ctls_list){ +void openflow_switch::rpc_list_ctls(std::list *ctls_list){ endpoint->list_ctls(ctls_list); } diff --git a/src/xdpd/openflow/openflow_switch.h b/src/xdpd/openflow/openflow_switch.h index 9d860eb9..1c79649e 100644 --- a/src/xdpd/openflow/openflow_switch.h +++ b/src/xdpd/openflow/openflow_switch.h @@ -100,7 +100,7 @@ class openflow_switch { virtual void rpc_disconnect_from_ctl(rofl::cctlid ctlid); - virtual void rpc_list_ctls(std::list); + virtual void rpc_list_ctls(std::list*); protected: /* From 00f592cba337d21c2634c80b129c859b035f167d Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Thu, 9 Jul 2015 11:14:45 +0200 Subject: [PATCH 05/19] Implemented ID assigned when adding a new controller --- src/xdpd/management/plugins/rest/sw-controllers.cc | 10 +++++----- src/xdpd/management/switch_manager.cc | 5 +++-- src/xdpd/management/switch_manager.h | 2 +- src/xdpd/openflow/openflow_switch.cc | 9 +++++---- src/xdpd/openflow/openflow_switch.h | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 8e23c969..93cb5bfc 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -456,7 +456,8 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: std::string proto, ip, port; enum rofl::csocket::socket_type_t socket_type; rofl::cparams socket_params; - //json_spirit::Object table; + json_spirit::Object table; + uint64_t assigned_id; //Perform security checks if(!authorised(req,rep)) return; @@ -516,8 +517,7 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: try{ ss<<"Adding Controller: " << lsi_name << " : " << proto; - //uint64_t id = switch_manager::rpc_connect_to_ctl(dpid, socket_type, socket_params); - switch_manager::rpc_connect_to_ctl(dpid, socket_type, socket_params); + assigned_id = switch_manager::rpc_connect_to_ctl(dpid, socket_type, socket_params); }catch(...){ //Something went wrong ss<<"Unable to add controller to lsi '"<rpc_connect_to_ctl(socket_type, socket_params); + uint64_t id = dp->rpc_connect_to_ctl(socket_type, socket_params); pthread_rwlock_unlock(&switch_manager::rwlock); + return id; } diff --git a/src/xdpd/management/switch_manager.h b/src/xdpd/management/switch_manager.h index f39db54a..6044a0bd 100644 --- a/src/xdpd/management/switch_manager.h +++ b/src/xdpd/management/switch_manager.h @@ -168,7 +168,7 @@ class switch_manager { /** * connect to controller */ - static void rpc_connect_to_ctl(uint64_t dpid, enum rofl::csocket::socket_type_t socket_type, rofl::cparams const& socket_params); + static uint64_t rpc_connect_to_ctl(uint64_t dpid, enum rofl::csocket::socket_type_t socket_type, rofl::cparams const& socket_params); /** * disconnect from from controller diff --git a/src/xdpd/openflow/openflow_switch.cc b/src/xdpd/openflow/openflow_switch.cc index 215d5ed8..cb56edf4 100644 --- a/src/xdpd/openflow/openflow_switch.cc +++ b/src/xdpd/openflow/openflow_switch.cc @@ -30,13 +30,14 @@ rofl_result_t openflow_switch::notify_port_status_changed(const switch_port_t* p /* * Connecting and disconnecting from a controller entity */ -void openflow_switch::rpc_connect_to_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params){ +uint64_t openflow_switch::rpc_connect_to_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params){ rofl::openflow::cofhello_elem_versionbitmap versionbitmap; versionbitmap.add_ofp_version(version); - //rofl::crofctl* ctl = endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap).connect(rofl::cauxid(0), socket_type, socket_params); - endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap).connect(rofl::cauxid(0), socket_type, socket_params); + rofl::crofctl &ctl = endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap); + ctl.connect(rofl::cauxid(0), socket_type, socket_params); + //endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap).connect(rofl::cauxid(0), socket_type, socket_params); - //return id; + return ctl.get_ctlid().get_ctlid(); } void openflow_switch::rpc_disconnect_from_ctl(rofl::cctlid ctlid){ diff --git a/src/xdpd/openflow/openflow_switch.h b/src/xdpd/openflow/openflow_switch.h index 1c79649e..494d7804 100644 --- a/src/xdpd/openflow/openflow_switch.h +++ b/src/xdpd/openflow/openflow_switch.h @@ -96,7 +96,7 @@ class openflow_switch { /** * Connecting and disconnecting from a controller entity */ - virtual void rpc_connect_to_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params); + virtual uint64_t rpc_connect_to_ctl(enum rofl::csocket::socket_type_t socket_type, cparams const& socket_params); virtual void rpc_disconnect_from_ctl(rofl::cctlid ctlid); From 16a2f3989f18bfcf9af9111df5308d1d2963ffb5 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Thu, 9 Jul 2015 11:31:57 +0200 Subject: [PATCH 06/19] Added warnings on add and remove controller malformed commands --- src/xdpd/management/plugins/rest/xcli | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/xdpd/management/plugins/rest/xcli b/src/xdpd/management/plugins/rest/xcli index cbcc1f58..2aa2c95a 100755 --- a/src/xdpd/management/plugins/rest/xcli +++ b/src/xdpd/management/plugins/rest/xcli @@ -340,6 +340,8 @@ def execute(socket, command, req_confirm=False): elif "add" in command: data = "" + if len(stripped) < 5: + return "Usage: exec add controller " if "controller" in command: data = parse_add_controller(stripped[4:]) try: @@ -347,14 +349,16 @@ def execute(socket, command, req_confirm=False): except Exception as e: return "error: "+str(e) else: - return "Usage: exec add controller " + return "Usage: exec add controller " elif "remove" in command: data = "" + if len(stripped) < 4: + return "Usage: exec remove controller " if "controller" in command: return rest(socket, compose_url(stripped), data, "DELETE") else: - return "Usage: exec remove controller " + return "Usage: exec remove controller " else: return rest(socket, compose_url(stripped), "", "POST") From ad421d6b4b0eee141fa6459769317c58ef78bd46 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Wed, 15 Jul 2015 17:14:59 +0200 Subject: [PATCH 07/19] Implementation of REST call show controller --- src/xdpd/management/plugins/rest/rest.cc | 4 +- .../management/plugins/rest/sw-controllers.cc | 47 ++++--- src/xdpd/management/plugins/rest/xcli | 4 +- .../snapshots/controller_snapshot.h | 131 ++++++++++++++++++ src/xdpd/management/switch_manager.cc | 15 ++ src/xdpd/management/switch_manager.h | 12 +- src/xdpd/openflow/openflow_switch.cc | 62 +++++++++ src/xdpd/openflow/openflow_switch.h | 8 ++ 8 files changed, 258 insertions(+), 25 deletions(-) create mode 100644 src/xdpd/management/snapshots/controller_snapshot.h diff --git a/src/xdpd/management/plugins/rest/rest.cc b/src/xdpd/management/plugins/rest/rest.cc index f3661fe1..6c83e528 100644 --- a/src/xdpd/management/plugins/rest/rest.cc +++ b/src/xdpd/management/plugins/rest/rest.cc @@ -104,8 +104,8 @@ static void srvthread (){ // handler.register_put_path("/mgmt/add/controller/(\\w+)", boost::bind(controllers::put::add_ctl, _1, _2, _3)); handler.register_delete_path("/mgmt/remove/controller/(\\w+)/(\\w+)", boost::bind(controllers::delete_::rem_ctl, _1, _2, _3)); - handler.register_get_path("/info/lsi/(\\w+)/ctls", boost::bind(controllers::get::list_ctls, _1, _2, _3)); - handler.register_get_path("/info/lsi/(\\w+)/ctl/(\\w+)", boost::bind(controllers::get::show_ctl, _1, _2, _3)); + handler.register_get_path("/info/lsi/(\\w+)/controllers", boost::bind(controllers::get::list_ctls, _1, _2, _3)); + handler.register_get_path("/info/lsi/(\\w+)/controller/(\\w+)", boost::bind(controllers::get::show_ctl, _1, _2, _3)); // //DELETE diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 93cb5bfc..9d8a7eba 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -237,7 +237,6 @@ void lsi_groups(const http::server::request &req, } void list_ctls(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ - fprintf(stderr,"LIST CONTROLLERS CALLED\n"); std::stringstream ss; std::string lsi_name; uint64_t dpid; @@ -249,8 +248,6 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost lsi_name = std::string(grps[1]); - fprintf(stderr,"listing controllers from lsi %s\n", lsi_name.c_str()); - // Get dpid try{ dpid = switch_manager::get_switch_dpid(lsi_name); @@ -261,13 +258,10 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost return; } - fprintf(stderr, "dpid %lu\n", dpid); - try{ ss<<"Listing controllers from: " << lsi_name; switch_manager::rpc_list_ctls(dpid, &list); }catch(...){ - fprintf(stderr, "ERROR switch_manager::rpc_list_ctls\n"); ss<<"Unable to get list of ctls from lsi '"< list_str; for(std::list::iterator it = list.begin(); it != list.end(); it++){ - fprintf(stderr,"found ctl-ID %lu\n", it->get_ctlid()); std::stringstream ss_tmp; ss_tmp << it->get_ctlid(); list_str.push_back(ss_tmp.str()); @@ -289,18 +282,18 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost } void show_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ - fprintf(stderr,"SHOW CONTROLLER CALLED\n"); std::stringstream ss; - std::string lsi_name, ctl_id; - uint64_t dpid; + std::string lsi_name; //, ctl_id; + uint64_t dpid, ctl_id; + controller_snapshot ctl_info; + json_spirit::Object wrap, list; //Perform security checks if(!authorised(req,rep)) return; lsi_name = std::string(grps[1]); - ctl_id = std::string(grps[2]); + ctl_id = atoi(std::string(grps[2]).c_str()); - fprintf(stderr,"showing controller from lsi %s, id %s\n", lsi_name.c_str(), ctl_id.c_str()); // Get dpid try{ @@ -312,16 +305,34 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: return; } - fprintf(stderr, "dpid %lu\n", dpid); -#if 0 try{ - ss<<"Listing controller info: " << lsi_name; - switch_manager::rpc_show_ctl(dpid, id, info); + ss<<"Showing Controller info: " << lsi_name; + switch_manager::get_controller_info(dpid, ctl_id, ctl_info); }catch(...){ - + ss<<"Unable to get Controller info for lsi " << lsi_name; + rep.content = ss.str(); + rep.status = http::server::reply::bad_request; + return; + } + + std::list conn_str; + std::list::const_iterator it; + for(it=ctl_info.conn_list.begin(); it != ctl_info.conn_list.end(); ++it){ + std::stringstream ss; + ss << *it; + conn_str.push_back(ss.str()); } + + std::stringstream ctl_ss; + ctl_ss << ctl_info; + + list.push_back(json_spirit::Pair("info", ctl_ss.str())); + json_spirit::Value conns_(conn_str.begin(), conn_str.end()); + list.push_back(json_spirit::Pair("Connections", conns_)); + //Return data -#endif + wrap.push_back(json_spirit::Pair("Controller", list)); + rep.content = json_spirit::write(wrap, true); } } //namespace get diff --git a/src/xdpd/management/plugins/rest/xcli b/src/xdpd/management/plugins/rest/xcli index 2aa2c95a..2d40f4bc 100755 --- a/src/xdpd/management/plugins/rest/xcli +++ b/src/xdpd/management/plugins/rest/xcli @@ -42,8 +42,8 @@ def list_show_commands(): string+= ' show lsi \t\t\t - Show LSI information\n' string+= ' show lsi table flows - Show LSI table flows\n' string+= ' show lsi group-table\t - List LSI group-table entries\n' - string+= ' show lsi ctls\t - List IDs of LSI\'s Controllers\n' - string+= ' show lsi ctl \t - Show Controller information\n' + string+= ' show lsi controllers\t - List IDs of LSI\'s Controllers\n' + string+= ' show lsi controller \t - Show Controller information\n' string+= ' show ports\t\t\t\t - List the available ports in the platform\n' string+= ' show port \t\t - Show port information\n' return string diff --git a/src/xdpd/management/snapshots/controller_snapshot.h b/src/xdpd/management/snapshots/controller_snapshot.h new file mode 100644 index 00000000..1c2821d7 --- /dev/null +++ b/src/xdpd/management/snapshots/controller_snapshot.h @@ -0,0 +1,131 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CONTROLLER_SNAPSHOT_H +#define CONTROLLER_SNAPSHOT_H + +//#include +//#include +//#include +//#include +//#include +//#include + +/** +* @file ctl_snapshot.h +* @author Victor Alvarez +* +* @brief C++ Controller snapshot +*/ + +namespace xdpd { + +class controller_conn_snapshot { +public: + + uint64_t id; + + typedef enum { + PROTOCOL_UNKNOWN, + PROTOCOL_PLAIN, + PROTOCOL_SSL, + }protocol_type_t; + + /** + * Protocol used: Plain/SSL + */ + protocol_type_t proto_type; + + /** + * IP + */ + std::string ip; + + /** + * Port + */ + uint64_t port; + + //Dumping operator + friend std::ostream& operator<<(std::ostream& os, const controller_conn_snapshot& c){ + os << "id: " << c.id << ", type: "; + switch (c.proto_type){ + case rofl::csocket::SOCKET_TYPE_UNKNOWN: + os << "Unkown"; + break; + case rofl::csocket::SOCKET_TYPE_PLAIN: + os << "Plain"; + break; + case rofl::csocket::SOCKET_TYPE_OPENSSL: + os << "SSL"; + break; + default: + assert(0); + os << "type error"; + break; + + } + os << ", IP: " << c.ip << ", port: " << c.port; + return os; + } +}; + +/** +* @brief C++ controller snapshot +* @ingroup cmm_mgmt +*/ +class controller_snapshot { + +public: + + uint64_t id; + + // Controller Mode + typedef enum { + CONTROLLER_MODE_MASTER, + CONTROLLER_MODE_SLAVE + }controller_role_t; + + /** + * Role ( Master / slave ) + */ + controller_role_t role; + + /** + * Status of the controller + */ + bool connected; + + /** + * List of connections + */ + std::list conn_list; + + //Dumping operator + friend std::ostream& operator<<(std::ostream& os, const controller_snapshot& c) + { + //TODO: Improve output + os << "{ id: " << c.id << ", Channel status: "; + if (c.connected){ + os << " Established"; + }else{ + os << " Not established"; + } + + os << ", Mode: "; + if (c.role == CONTROLLER_MODE_MASTER){ + os << "Master"; + }else{ + os << "Slave"; + } + os << "}"; + return os; + } + +}; + + +}// namespace xdpd + +#endif /* CTL_SNAPSHOT_H_ */ diff --git a/src/xdpd/management/switch_manager.cc b/src/xdpd/management/switch_manager.cc index c48326a8..edd80aee 100644 --- a/src/xdpd/management/switch_manager.cc +++ b/src/xdpd/management/switch_manager.cc @@ -439,6 +439,21 @@ switch_manager::rpc_list_ctls(uint64_t dpid, std::list* list){ } +void switch_manager::get_controller_info(uint64_t dpid, uint64_t ctl_id, controller_snapshot& ctl_info){ + + pthread_rwlock_wrlock(&switch_manager::rwlock); + + if (switch_manager::switchs.find(dpid) == switch_manager::switchs.end()){ + pthread_rwlock_unlock(&switch_manager::rwlock); + throw eOfSmDoesNotExist(); + } + + //Get switch instance + openflow_switch* dp = switch_manager::switchs[dpid]; + dp->get_controller_info(ctl_id, ctl_info); + + pthread_rwlock_unlock(&switch_manager::rwlock); +} // // Other configuration parameters diff --git a/src/xdpd/management/switch_manager.h b/src/xdpd/management/switch_manager.h index 6044a0bd..cd4c88c8 100644 --- a/src/xdpd/management/switch_manager.h +++ b/src/xdpd/management/switch_manager.h @@ -34,6 +34,7 @@ #include "snapshots/switch_snapshot.h" #include "snapshots/flow_entry_snapshot.h" #include "snapshots/group_mod_snapshot.h" +#include "snapshots/controller_snapshot.h" /** * @file switch_manager.h @@ -166,20 +167,25 @@ class switch_manager { // /** - * connect to controller + * Connect to controller */ static uint64_t rpc_connect_to_ctl(uint64_t dpid, enum rofl::csocket::socket_type_t socket_type, rofl::cparams const& socket_params); /** - * disconnect from from controller + * Disconnect from from controller */ static void rpc_disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid); /** - * list the available controllers ids + * List the available controllers ids */ static void rpc_list_ctls(uint64_t dpid, std::list *list); + /** + * Get detailed information of a specific controller + */ + static void get_controller_info(uint64_t dpid, uint64_t ctl_id, controller_snapshot& ctl_info); + // // Other configuration parameters // diff --git a/src/xdpd/openflow/openflow_switch.cc b/src/xdpd/openflow/openflow_switch.cc index cb56edf4..d40333e2 100644 --- a/src/xdpd/openflow/openflow_switch.cc +++ b/src/xdpd/openflow/openflow_switch.cc @@ -1,4 +1,5 @@ #include "openflow_switch.h" +#include "../management/snapshots/controller_snapshot.h" using namespace rofl; using namespace xdpd; @@ -53,3 +54,64 @@ void openflow_switch::rpc_disconnect_from_ctl(rofl::cctlid ctlid){ void openflow_switch::rpc_list_ctls(std::list *ctls_list){ endpoint->list_ctls(ctls_list); } + +void openflow_switch::get_controller_info(uint64_t ctl_id, controller_snapshot& ctl_info){ + + // Get Controller + rofl::cctlid ctlid(ctl_id); + const rofl::crofctl &ctl = endpoint->get_ctl(ctlid); + + // Get info for snapshot (Role, Status, SSL, IP, port) + ctl_info.id = ctl_id; + // Role Master / Slave + if (ctl.is_slave()){ + ctl_info.role = controller_snapshot::CONTROLLER_MODE_SLAVE; + } else { + ctl_info.role = controller_snapshot::CONTROLLER_MODE_MASTER; + } + + // Status + ctl_info.connected = ctl.is_established(); + + // lets see what is in each connection. + std::list conn_list = ctl.get_conn_index(); + for(std::list::iterator it = conn_list.begin(); it != conn_list.end(); it++){ + + controller_conn_snapshot conn; + + conn.id = it->get_id(); + + // Connection type plain/ssl + rofl::csocket::socket_type_t stype = ctl.rofchan.get_conn(*it).get_rofsocket().get_socket().get_socket_type(); + switch (stype){ + case rofl::csocket::SOCKET_TYPE_UNKNOWN: + conn.proto_type = controller_conn_snapshot::PROTOCOL_UNKNOWN; + break; + case rofl::csocket::SOCKET_TYPE_PLAIN: + conn.proto_type = controller_conn_snapshot::PROTOCOL_PLAIN; + break; + case rofl::csocket::SOCKET_TYPE_OPENSSL: + conn.proto_type = controller_conn_snapshot::PROTOCOL_SSL; + break; + default: + assert(0); + break; + } + + rofl::cparams sparams = ctl.rofchan.get_conn(*it).get_rofsocket().get_socket().get_socket_params(); + + // Hostname / IP address + rofl::cparam hostname = sparams.get_param(rofl::csocket::PARAM_KEY_REMOTE_HOSTNAME); + conn.ip = hostname.get_string(); + + // Port + conn.port = sparams.get_param(rofl::csocket::PARAM_KEY_REMOTE_PORT).get_uint(); + + // Add connection to connection array + ctl_info.conn_list.push_back(conn); + + } +} + + + diff --git a/src/xdpd/openflow/openflow_switch.h b/src/xdpd/openflow/openflow_switch.h index 494d7804..fc2a643f 100644 --- a/src/xdpd/openflow/openflow_switch.h +++ b/src/xdpd/openflow/openflow_switch.h @@ -22,6 +22,9 @@ namespace xdpd { +// Fwd declaration for controller snapshot +class controller_snapshot; + /** * @brief Version-agnostic abstraction of a complete * (logical) OpenFlow switch. @@ -100,8 +103,13 @@ class openflow_switch { virtual void rpc_disconnect_from_ctl(rofl::cctlid ctlid); + /** + * Getting information about controllers + */ virtual void rpc_list_ctls(std::list*); + virtual void get_controller_info(uint64_t ctl_id, xdpd::controller_snapshot& ctl_info); + protected: /* * Pure virtual method that must be implemented by derived classes From d46f6f62da862a3f972cecaeef091a835ddb538b Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Mon, 20 Jul 2015 16:32:26 +0200 Subject: [PATCH 08/19] Added examples exec add/remove controller to xcli --- src/xdpd/management/plugins/rest/xcli | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xdpd/management/plugins/rest/xcli b/src/xdpd/management/plugins/rest/xcli index 2d40f4bc..0eea0882 100755 --- a/src/xdpd/management/plugins/rest/xcli +++ b/src/xdpd/management/plugins/rest/xcli @@ -65,6 +65,8 @@ def list_exec_commands(): string+=' exec attach port ge0 dp0\n' string+=' exec create lsi dp1 256 1.3 8\n' string+=' exec create lsi dp1 256 1.2 2 matching-algorithms={"loop", "l2hash"}\n' + string+=' exec add controller dp1 tcp:192.168.1.1:6633\n' + string+=' exec remove controller dp1 3\n' return string def usage(): From 1ec0b919f784926b9c83493f322caacb08d73381 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Mon, 20 Jul 2015 16:34:38 +0200 Subject: [PATCH 09/19] Changed the structure of the information of the controllers for better parsing --- .../management/plugins/rest/sw-controllers.cc | 28 +++++----- .../snapshots/controller_snapshot.h | 53 ++++++++++--------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 9d8a7eba..805a887b 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -286,7 +286,7 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: std::string lsi_name; //, ctl_id; uint64_t dpid, ctl_id; controller_snapshot ctl_info; - json_spirit::Object wrap, list; + json_spirit::Object j_wrap, j_ctl, j_list; //Perform security checks if(!authorised(req,rep)) return; @@ -315,24 +315,28 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: return; } - std::list conn_str; + j_ctl.push_back(json_spirit::Pair("id", ctl_info.id)); + j_ctl.push_back(json_spirit::Pair("channel-status", ctl_info.get_status_str())); + j_ctl.push_back(json_spirit::Pair("mode", ctl_info.get_role_str())); + std::list::const_iterator it; for(it=ctl_info.conn_list.begin(); it != ctl_info.conn_list.end(); ++it){ + json_spirit::Object j_conn; + j_conn.push_back(json_spirit::Pair("protocol-type", it->get_proto_type_str())); + j_conn.push_back(json_spirit::Pair("ip", it->ip)); + j_conn.push_back(json_spirit::Pair("port", it->port)); + std::stringstream ss; - ss << *it; - conn_str.push_back(ss.str()); + ss << it->id; + j_list.push_back(json_spirit::Pair(ss.str(), j_conn)); + } - std::stringstream ctl_ss; - ctl_ss << ctl_info; - - list.push_back(json_spirit::Pair("info", ctl_ss.str())); - json_spirit::Value conns_(conn_str.begin(), conn_str.end()); - list.push_back(json_spirit::Pair("Connections", conns_)); + j_ctl.push_back(json_spirit::Pair("connections", j_list)); //Return data - wrap.push_back(json_spirit::Pair("Controller", list)); - rep.content = json_spirit::write(wrap, true); + j_wrap.push_back(json_spirit::Pair("Controller", j_ctl)); + rep.content = json_spirit::write(j_wrap, true); } } //namespace get diff --git a/src/xdpd/management/snapshots/controller_snapshot.h b/src/xdpd/management/snapshots/controller_snapshot.h index 1c2821d7..0df94ca2 100644 --- a/src/xdpd/management/snapshots/controller_snapshot.h +++ b/src/xdpd/management/snapshots/controller_snapshot.h @@ -47,25 +47,23 @@ class controller_conn_snapshot { */ uint64_t port; - //Dumping operator - friend std::ostream& operator<<(std::ostream& os, const controller_conn_snapshot& c){ - os << "id: " << c.id << ", type: "; - switch (c.proto_type){ + std::string get_proto_type_str(void) const { + switch (this->proto_type){ case rofl::csocket::SOCKET_TYPE_UNKNOWN: - os << "Unkown"; - break; + return "unkown"; case rofl::csocket::SOCKET_TYPE_PLAIN: - os << "Plain"; - break; + return "plain"; case rofl::csocket::SOCKET_TYPE_OPENSSL: - os << "SSL"; - break; + return "ssl"; default: assert(0); - os << "type error"; - break; - + return "type error"; } + } + //Dumping operator + friend std::ostream& operator<<(std::ostream& os, const controller_conn_snapshot& c){ + os << "id: " << c.id << ", type: "; + os << c.get_proto_type_str(); os << ", IP: " << c.ip << ", port: " << c.port; return os; } @@ -102,23 +100,26 @@ class controller_snapshot { */ std::list conn_list; + std::string get_status_str(void) const { + if (this->connected) + return "established"; + else + return "not-established"; + } + + std::string get_role_str(void) const { + if (this->role == CONTROLLER_MODE_MASTER) + return "master"; + else + return "slave"; + } + //Dumping operator friend std::ostream& operator<<(std::ostream& os, const controller_snapshot& c) { //TODO: Improve output - os << "{ id: " << c.id << ", Channel status: "; - if (c.connected){ - os << " Established"; - }else{ - os << " Not established"; - } - - os << ", Mode: "; - if (c.role == CONTROLLER_MODE_MASTER){ - os << "Master"; - }else{ - os << "Slave"; - } + os << "{ id: " << c.id << ", Channel status: " << c.get_status_str(); + os << ", Mode: " << c.get_role_str(); os << "}"; return os; } From 9f334e9973945bd5300b52f3066f25d7308820f1 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Mon, 20 Jul 2015 16:47:24 +0200 Subject: [PATCH 10/19] Erased "rpc" from calls to the switch manager. Using only read lock when gathering info of controllers --- .../management/plugins/config/openflow/lsi_scope.cc | 2 +- src/xdpd/management/plugins/rest/sw-controllers.cc | 6 +++--- src/xdpd/management/switch_manager.cc | 10 +++++----- src/xdpd/management/switch_manager.h | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/xdpd/management/plugins/config/openflow/lsi_scope.cc b/src/xdpd/management/plugins/config/openflow/lsi_scope.cc index 0357d05f..9806897d 100644 --- a/src/xdpd/management/plugins/config/openflow/lsi_scope.cc +++ b/src/xdpd/management/plugins/config/openflow/lsi_scope.cc @@ -294,7 +294,7 @@ void lsi_scope::post_validate(libconfig::Setting& setting, bool dry_run){ //Connect(1..N-1) for(std::vector::iterator it = (conns.begin()+1); it != conns.end(); ++it) { - switch_manager::rpc_connect_to_ctl(dpid, it->type, it->params); + switch_manager::connect_to_ctl(dpid, it->type, it->params); } } } diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 805a887b..62aedfc3 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -260,7 +260,7 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost try{ ss<<"Listing controllers from: " << lsi_name; - switch_manager::rpc_list_ctls(dpid, &list); + switch_manager::list_ctls(dpid, &list); }catch(...){ ss<<"Unable to get list of ctls from lsi '"<* list){ - pthread_rwlock_wrlock(&switch_manager::rwlock); +switch_manager::list_ctls(uint64_t dpid, std::list* list){ + pthread_rwlock_rdlock(&switch_manager::rwlock); if (switch_manager::switchs.find(dpid) == switch_manager::switchs.end()){ pthread_rwlock_unlock(&switch_manager::rwlock); @@ -441,7 +441,7 @@ switch_manager::rpc_list_ctls(uint64_t dpid, std::list* list){ void switch_manager::get_controller_info(uint64_t dpid, uint64_t ctl_id, controller_snapshot& ctl_info){ - pthread_rwlock_wrlock(&switch_manager::rwlock); + pthread_rwlock_rdlock(&switch_manager::rwlock); if (switch_manager::switchs.find(dpid) == switch_manager::switchs.end()){ pthread_rwlock_unlock(&switch_manager::rwlock); diff --git a/src/xdpd/management/switch_manager.h b/src/xdpd/management/switch_manager.h index cd4c88c8..c794ff49 100644 --- a/src/xdpd/management/switch_manager.h +++ b/src/xdpd/management/switch_manager.h @@ -169,17 +169,17 @@ class switch_manager { /** * Connect to controller */ - static uint64_t rpc_connect_to_ctl(uint64_t dpid, enum rofl::csocket::socket_type_t socket_type, rofl::cparams const& socket_params); + static uint64_t connect_to_ctl(uint64_t dpid, enum rofl::csocket::socket_type_t socket_type, rofl::cparams const& socket_params); /** * Disconnect from from controller */ - static void rpc_disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid); + static void disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid); /** * List the available controllers ids */ - static void rpc_list_ctls(uint64_t dpid, std::list *list); + static void list_ctls(uint64_t dpid, std::list *list); /** * Get detailed information of a specific controller From 63f7247b08b76aaf133261d628a9049220462b9e Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Mon, 20 Jul 2015 17:04:23 +0200 Subject: [PATCH 11/19] Small fix in label of controller information --- src/xdpd/management/plugins/rest/sw-controllers.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 62aedfc3..8216a48c 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -277,7 +277,7 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost } json_spirit::Value ids_(list_str.begin(), list_str.end()); - table.push_back(json_spirit::Pair("ids", ids_)); + table.push_back(json_spirit::Pair("controller-ids", ids_)); rep.content = json_spirit::write(table, true); } From f7a42b0cdb0b73fd3eeceabbec794a72a766310d Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Tue, 21 Jul 2015 11:23:08 +0200 Subject: [PATCH 12/19] Added Equal as a role for controllers and using get_role() in crofbase to get the role --- .../snapshots/controller_snapshot.h | 18 ++++++------- src/xdpd/openflow/openflow_switch.cc | 26 +++++++++++-------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/xdpd/management/snapshots/controller_snapshot.h b/src/xdpd/management/snapshots/controller_snapshot.h index 0df94ca2..c070035b 100644 --- a/src/xdpd/management/snapshots/controller_snapshot.h +++ b/src/xdpd/management/snapshots/controller_snapshot.h @@ -5,13 +5,6 @@ #ifndef CONTROLLER_SNAPSHOT_H #define CONTROLLER_SNAPSHOT_H -//#include -//#include -//#include -//#include -//#include -//#include - /** * @file ctl_snapshot.h * @author Victor Alvarez @@ -81,6 +74,7 @@ class controller_snapshot { // Controller Mode typedef enum { + CONTROLLER_MODE_EQUAL, CONTROLLER_MODE_MASTER, CONTROLLER_MODE_SLAVE }controller_role_t; @@ -108,10 +102,16 @@ class controller_snapshot { } std::string get_role_str(void) const { - if (this->role == CONTROLLER_MODE_MASTER) + if (this->role == CONTROLLER_MODE_EQUAL) + return "equal"; + else if (this->role == CONTROLLER_MODE_MASTER) return "master"; - else + else if (this->role == CONTROLLER_MODE_SLAVE) return "slave"; + else{ + assert(0); + return "error"; + } } //Dumping operator diff --git a/src/xdpd/openflow/openflow_switch.cc b/src/xdpd/openflow/openflow_switch.cc index d40333e2..6177ea6d 100644 --- a/src/xdpd/openflow/openflow_switch.cc +++ b/src/xdpd/openflow/openflow_switch.cc @@ -36,19 +36,13 @@ uint64_t openflow_switch::rpc_connect_to_ctl(enum rofl::csocket::socket_type_t s versionbitmap.add_ofp_version(version); rofl::crofctl &ctl = endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap); ctl.connect(rofl::cauxid(0), socket_type, socket_params); - //endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap).connect(rofl::cauxid(0), socket_type, socket_params); return ctl.get_ctlid().get_ctlid(); } void openflow_switch::rpc_disconnect_from_ctl(rofl::cctlid ctlid){ - // TODO check for a valid ID - //if (endpoint->has_ctl(ctlid)){ + //NOTE need to check for existance? if (endpoint->has_ctl(ctlid)) endpoint->drop_ctl(ctlid); - //} - //else { - // throw eOfSmNotFound; - //} } void openflow_switch::rpc_list_ctls(std::list *ctls_list){ @@ -64,10 +58,20 @@ void openflow_switch::get_controller_info(uint64_t ctl_id, controller_snapshot& // Get info for snapshot (Role, Status, SSL, IP, port) ctl_info.id = ctl_id; // Role Master / Slave - if (ctl.is_slave()){ - ctl_info.role = controller_snapshot::CONTROLLER_MODE_SLAVE; - } else { - ctl_info.role = controller_snapshot::CONTROLLER_MODE_MASTER; + switch (ctl.get_role().get_role()){ + // WARNING the openflow version specific types should be abstracted from the API + case rofl::openflow12::OFPCR_ROLE_EQUAL: + ctl_info.role = controller_snapshot::CONTROLLER_MODE_EQUAL; + break; + case rofl::openflow12::OFPCR_ROLE_SLAVE: + ctl_info.role = controller_snapshot::CONTROLLER_MODE_SLAVE; + break; + case rofl::openflow12::OFPCR_ROLE_MASTER: + ctl_info.role = controller_snapshot::CONTROLLER_MODE_MASTER; + break; + default: + //TODO error + break; } // Status From 1902f12b5bc0828db26beaff86ee6cbfad4344d2 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Tue, 21 Jul 2015 11:23:39 +0200 Subject: [PATCH 13/19] Cleaning old commnents --- src/xdpd/management/plugins/rest/sw-controllers.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 8216a48c..aa4f99b1 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -517,13 +517,11 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: } - //fprintf(stderr,"found proto: %s\n ip %s\n port %s\n", proto.c_str(), ip.c_str(), port.c_str()); //TODO Check parameters received (proto, ip & port) if ( proto == "tcp" ){ socket_type = rofl::csocket::SOCKET_TYPE_PLAIN; } else { - //Other types not supported - // TODO add SOCKET_TYPE_OPENSSL + // TODO Other types not yet supported (SOCKET_TYPE_OPENSSL) return; } socket_params = rofl::csocket::get_default_params(socket_type); From d4ee5e7a4ff7e9579e2c8b2521916c69f8d1a99c Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Tue, 28 Jul 2015 15:45:09 +0200 Subject: [PATCH 14/19] Following previuos order in register of REST calls --- src/xdpd/management/plugins/rest/rest.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/xdpd/management/plugins/rest/rest.cc b/src/xdpd/management/plugins/rest/rest.cc index 6c83e528..716ddec9 100644 --- a/src/xdpd/management/plugins/rest/rest.cc +++ b/src/xdpd/management/plugins/rest/rest.cc @@ -82,6 +82,10 @@ static void srvthread (){ handler.register_get_path("/info/lsi/(\\w+)/table/([0-9]+)/flows", boost::bind(controllers::get::lsi_table_flows, _1, _2, _3)); handler.register_get_path("/info/lsi/(\\w+)/group-table", boost::bind(controllers::get::lsi_groups, _1, _2, _3)); + //Controllers + handler.register_get_path("/info/lsi/(\\w+)/controllers", boost::bind(controllers::get::list_ctls, _1, _2, _3)); + handler.register_get_path("/info/lsi/(\\w+)/controller/(\\w+)", boost::bind(controllers::get::show_ctl, _1, _2, _3)); + // // POST // @@ -99,19 +103,17 @@ static void srvthread (){ handler.register_post_path("/mgmt/create/lsi", boost::bind(controllers::put::create_lsi, _1, _2, _3)); handler.register_put_path("/mgmt/create/vlink/(\\w+)/(\\w+)", boost::bind(controllers::put::create_vlink, _1, _2, _3)); - // - // CONTROLLERS - // + // Controllers handler.register_put_path("/mgmt/add/controller/(\\w+)", boost::bind(controllers::put::add_ctl, _1, _2, _3)); - handler.register_delete_path("/mgmt/remove/controller/(\\w+)/(\\w+)", boost::bind(controllers::delete_::rem_ctl, _1, _2, _3)); - handler.register_get_path("/info/lsi/(\\w+)/controllers", boost::bind(controllers::get::list_ctls, _1, _2, _3)); - handler.register_get_path("/info/lsi/(\\w+)/controller/(\\w+)", boost::bind(controllers::get::show_ctl, _1, _2, _3)); // //DELETE // handler.register_delete_path("/mgmt/destroy/lsi/(\\w+)", boost::bind(controllers::delete_::destroy_switch, _1, _2, _3)); + // Controllers + handler.register_delete_path("/mgmt/remove/controller/(\\w+)/(\\w+)", boost::bind(controllers::delete_::rem_ctl, _1, _2, _3)); + //Recover host and port parse_bind_addr(host, port); From 5448b4924fca150d89c98c469b2025d6bd5ca7b3 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Tue, 28 Jul 2015 17:13:10 +0200 Subject: [PATCH 15/19] Changed the way we handle errors in management of controllers with REST --- .../management/plugins/rest/sw-controllers.cc | 60 ++++++++----------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index aa4f99b1..df1e4fff 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -249,23 +249,21 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost lsi_name = std::string(grps[1]); // Get dpid - try{ - dpid = switch_manager::get_switch_dpid(lsi_name); - }catch(...){ - ss<<"Unable to find a dpid for lsi " << lsi_name; + if(!switch_manager::exists_by_name(lsi_name)){ + //Throw 404 + std::stringstream ss; + ss<<"Invalid lsi '"< Date: Tue, 28 Jul 2015 17:30:33 +0200 Subject: [PATCH 16/19] Removed unnecessary spaces --- .../plugins/config/openflow/lsi_scope.cc | 2 +- .../management/plugins/rest/put-controllers.h | 4 ++-- .../management/plugins/rest/sw-controllers.cc | 20 +++++++++---------- src/xdpd/management/plugins/rest/xcli | 8 ++++---- .../snapshots/controller_snapshot.h | 15 +++++++------- src/xdpd/management/switch_manager.cc | 4 ++-- src/xdpd/openflow/openflow_switch.cc | 6 +----- 7 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/xdpd/management/plugins/config/openflow/lsi_scope.cc b/src/xdpd/management/plugins/config/openflow/lsi_scope.cc index 9806897d..99c59223 100644 --- a/src/xdpd/management/plugins/config/openflow/lsi_scope.cc +++ b/src/xdpd/management/plugins/config/openflow/lsi_scope.cc @@ -294,7 +294,7 @@ void lsi_scope::post_validate(libconfig::Setting& setting, bool dry_run){ //Connect(1..N-1) for(std::vector::iterator it = (conns.begin()+1); it != conns.end(); ++it) { - switch_manager::connect_to_ctl(dpid, it->type, it->params); + switch_manager::connect_to_ctl(dpid, it->type, it->params); } } } diff --git a/src/xdpd/management/plugins/rest/put-controllers.h b/src/xdpd/management/plugins/rest/put-controllers.h index baa1647e..eab56533 100644 --- a/src/xdpd/management/plugins/rest/put-controllers.h +++ b/src/xdpd/management/plugins/rest/put-controllers.h @@ -17,11 +17,11 @@ namespace put{ * Create a vlink */ void create_vlink(const http::server::request &, http::server::reply &, boost::cmatch&); - + /* * Add a new controller to the LSI */ - void add_ctl(const http::server::request &, http::server::reply &, boost::cmatch&); + void add_ctl(const http::server::request &, http::server::reply &, boost::cmatch&); } //namespace put } //namespace controllers diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index df1e4fff..85d9a05f 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -242,7 +242,7 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost uint64_t dpid; std::list list; json_spirit::Object table; - + //Perform security checks if(!authorised(req,rep)) return; @@ -258,7 +258,7 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost return; } dpid = switch_manager::get_switch_dpid(lsi_name); - + ss<<"Listing controllers from: " << lsi_name; try{ switch_manager::list_ctls(dpid, &list); @@ -285,7 +285,7 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: uint64_t dpid, ctl_id; controller_snapshot ctl_info; json_spirit::Object j_wrap, j_ctl, j_list; - + //Perform security checks if(!authorised(req,rep)) return; @@ -310,7 +310,7 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: switch_manager::get_controller_info(dpid, ctl_id, ctl_info); }catch(...){ throw "Unable to get Controller info for lsi"; - } + } j_ctl.push_back(json_spirit::Pair("id", ctl_info.id)); j_ctl.push_back(json_spirit::Pair("channel-status", ctl_info.get_status_str())); @@ -326,7 +326,7 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: std::stringstream ss; ss << it->id; j_list.push_back(json_spirit::Pair(ss.str(), j_conn)); - + } j_ctl.push_back(json_spirit::Pair("connections", j_list)); @@ -470,7 +470,7 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: rofl::cparams socket_params; json_spirit::Object table; uint64_t assigned_id; - + //Perform security checks if(!authorised(req,rep)) return; @@ -486,9 +486,9 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: return; } - // Get dpid TODO check for failure + // Get dpid check for failure uint64_t dpid = switch_manager::get_switch_dpid(lsi_name); - + // Parse data (protocol, IP & port) try{ //Parse the input @@ -535,7 +535,7 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: }catch(...){ throw "Unable to add controller to lsi"; } - + //Return assigned ID table.push_back(json_spirit::Pair("assigned id", assigned_id)); rep.content = json_spirit::write(table, true); @@ -586,7 +586,7 @@ void rem_ctl(const http::server::request &req, http::server::reply &rep, boost:: uint64_t dpid, ctl_id; //Perform security checks - if(!authorised(req,rep)) return; + if(!authorised(req,rep)) return; lsi_name = std::string(grps[1]); ctlid_str = std::string(grps[2]); diff --git a/src/xdpd/management/plugins/rest/xcli b/src/xdpd/management/plugins/rest/xcli index 0eea0882..82eebc6e 100755 --- a/src/xdpd/management/plugins/rest/xcli +++ b/src/xdpd/management/plugins/rest/xcli @@ -184,7 +184,7 @@ def parse_add_controller(params): obj = {} ctl = obj["ctl"] = {} splitted_vec = params[0].split(':') - + # Check number of parameters if len(splitted_vec) != 3: raise Exception("Wrong number of parameters. Use protocol:ip:port\nExample tcp:192.0.0.55:6633") @@ -193,13 +193,13 @@ def parse_add_controller(params): ctl["proto"] = "tcp" elif splitted_vec[0] == "tcp+tls": raise Exception("TLS not yet supported") - + if splitted_vec[1] == "": #TODO check valid ip (dots, ping?) raise Exception("Invalid IP") else: ctl["ip"] = splitted_vec[1] - + if splitted_vec[2] == "": raise Exception("Error: Invalid port") else: @@ -348,7 +348,7 @@ def execute(socket, command, req_confirm=False): data = parse_add_controller(stripped[4:]) try: return rest(socket, compose_url(stripped[:4]), data, "PUT") - except Exception as e: + except Exception as e: return "error: "+str(e) else: return "Usage: exec add controller " diff --git a/src/xdpd/management/snapshots/controller_snapshot.h b/src/xdpd/management/snapshots/controller_snapshot.h index c070035b..02facde0 100644 --- a/src/xdpd/management/snapshots/controller_snapshot.h +++ b/src/xdpd/management/snapshots/controller_snapshot.h @@ -3,10 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef CONTROLLER_SNAPSHOT_H -#define CONTROLLER_SNAPSHOT_H +#define CONTROLLER_SNAPSHOT_H /** -* @file ctl_snapshot.h +* @file ctl_snapshot.h * @author Victor Alvarez * * @brief C++ Controller snapshot @@ -29,7 +29,7 @@ class controller_conn_snapshot { * Protocol used: Plain/SSL */ protocol_type_t proto_type; - + /** * IP */ @@ -53,7 +53,7 @@ class controller_conn_snapshot { return "type error"; } } - //Dumping operator + //Dumping operator friend std::ostream& operator<<(std::ostream& os, const controller_conn_snapshot& c){ os << "id: " << c.id << ", type: "; os << c.get_proto_type_str(); @@ -63,12 +63,12 @@ class controller_conn_snapshot { }; /** -* @brief C++ controller snapshot +* @brief C++ controller snapshot * @ingroup cmm_mgmt */ class controller_snapshot { -public: +public: uint64_t id; @@ -114,10 +114,9 @@ class controller_snapshot { } } - //Dumping operator + //Dumping operator friend std::ostream& operator<<(std::ostream& os, const controller_snapshot& c) { - //TODO: Improve output os << "{ id: " << c.id << ", Channel status: " << c.get_status_str(); os << ", Mode: " << c.get_role_str(); os << "}"; diff --git a/src/xdpd/management/switch_manager.cc b/src/xdpd/management/switch_manager.cc index 0c5aa95e..f34ed251 100644 --- a/src/xdpd/management/switch_manager.cc +++ b/src/xdpd/management/switch_manager.cc @@ -426,7 +426,7 @@ switch_manager::disconnect_from_ctl(uint64_t dpid, rofl::cctlid ctlid){ void switch_manager::list_ctls(uint64_t dpid, std::list* list){ pthread_rwlock_rdlock(&switch_manager::rwlock); - + if (switch_manager::switchs.find(dpid) == switch_manager::switchs.end()){ pthread_rwlock_unlock(&switch_manager::rwlock); throw eOfSmDoesNotExist(); @@ -442,7 +442,7 @@ switch_manager::list_ctls(uint64_t dpid, std::list* list){ void switch_manager::get_controller_info(uint64_t dpid, uint64_t ctl_id, controller_snapshot& ctl_info){ pthread_rwlock_rdlock(&switch_manager::rwlock); - + if (switch_manager::switchs.find(dpid) == switch_manager::switchs.end()){ pthread_rwlock_unlock(&switch_manager::rwlock); throw eOfSmDoesNotExist(); diff --git a/src/xdpd/openflow/openflow_switch.cc b/src/xdpd/openflow/openflow_switch.cc index 6177ea6d..763ec49e 100644 --- a/src/xdpd/openflow/openflow_switch.cc +++ b/src/xdpd/openflow/openflow_switch.cc @@ -36,7 +36,7 @@ uint64_t openflow_switch::rpc_connect_to_ctl(enum rofl::csocket::socket_type_t s versionbitmap.add_ofp_version(version); rofl::crofctl &ctl = endpoint->add_ctl(endpoint->get_idle_ctlid(), versionbitmap); ctl.connect(rofl::cauxid(0), socket_type, socket_params); - + return ctl.get_ctlid().get_ctlid(); } @@ -82,7 +82,6 @@ void openflow_switch::get_controller_info(uint64_t ctl_id, controller_snapshot& for(std::list::iterator it = conn_list.begin(); it != conn_list.end(); it++){ controller_conn_snapshot conn; - conn.id = it->get_id(); // Connection type plain/ssl @@ -116,6 +115,3 @@ void openflow_switch::get_controller_info(uint64_t ctl_id, controller_snapshot& } } - - - From 34a16a1970d9372c4948f60026686e4cee4d5d20 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Tue, 28 Jul 2015 18:22:19 +0200 Subject: [PATCH 17/19] Deleted unnecessary stringstreams --- src/xdpd/management/plugins/rest/sw-controllers.cc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 85d9a05f..f82653ca 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -237,7 +237,6 @@ void lsi_groups(const http::server::request &req, } void list_ctls(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ - std::stringstream ss; std::string lsi_name; uint64_t dpid; std::list list; @@ -259,7 +258,6 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost } dpid = switch_manager::get_switch_dpid(lsi_name); - ss<<"Listing controllers from: " << lsi_name; try{ switch_manager::list_ctls(dpid, &list); }catch(...){ @@ -280,7 +278,6 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost } void show_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ - std::stringstream ss; std::string lsi_name; //, ctl_id; uint64_t dpid, ctl_id; controller_snapshot ctl_info; @@ -305,7 +302,6 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: dpid = switch_manager::get_switch_dpid(lsi_name); - ss<<"Showing Controller info: " << lsi_name; try{ switch_manager::get_controller_info(dpid, ctl_id, ctl_info); }catch(...){ @@ -464,7 +460,6 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: //call switch_manager to add a new controller to the LSI // get IP & port from the req parameter (json?) // check IP & port (if there is already a controller there, send error message) - std::stringstream ss; std::string proto, ip, port; enum rofl::csocket::socket_type_t socket_type; rofl::cparams socket_params; @@ -506,7 +501,7 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: port = json_spirit::find_value(obj, "port").get_str(); }catch(...){ - //Something went wrong + std::stringstream ss; ss<<"Unable to parse arguments for add controller"; rep.content = ss.str(); rep.status = http::server::reply::bad_request; @@ -529,7 +524,6 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: socket_params.set_param(rofl::csocket::PARAM_KEY_REMOTE_HOSTNAME) = ip; socket_params.set_param(rofl::csocket::PARAM_KEY_REMOTE_PORT) = port; - ss<<"Adding Controller: " << lsi_name << " : " << proto; try{ assigned_id = switch_manager::connect_to_ctl(dpid, socket_type, socket_params); }catch(...){ @@ -580,7 +574,6 @@ void destroy_switch(const http::server::request &req, http::server::reply &rep, void rem_ctl(const http::server::request &req, http::server::reply &rep, boost::cmatch& grps){ - std::stringstream ss; std::string lsi_name; std::string ctlid_str; uint64_t dpid, ctl_id; @@ -608,7 +601,6 @@ void rem_ctl(const http::server::request &req, http::server::reply &rep, boost:: ctl_id = atoi(ctlid_str.c_str()); rofl::cctlid ctlid(ctl_id); - ss<<"Removing Controller: " << lsi_name << " : " << ctlid_str; try{ switch_manager::disconnect_from_ctl(dpid, ctlid); }catch(...){ From 2f5295d1b632cb7c43f658348f36e4a2f6e2df96 Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Wed, 29 Jul 2015 14:04:26 +0200 Subject: [PATCH 18/19] Polish of REST management of controllers - List and show controllers don't require authorized access - Fixed return message after adding a new controller - Capturing exception when parsing the parameters of the new controller in xcli - New APIs listed in the index --- src/xdpd/management/plugins/rest/misc-controllers.cc | 4 ++++ src/xdpd/management/plugins/rest/sw-controllers.cc | 10 ++-------- src/xdpd/management/plugins/rest/xcli | 5 ++++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/xdpd/management/plugins/rest/misc-controllers.cc b/src/xdpd/management/plugins/rest/misc-controllers.cc index 0a2bb14d..a14c6293 100644 --- a/src/xdpd/management/plugins/rest/misc-controllers.cc +++ b/src/xdpd/management/plugins/rest/misc-controllers.cc @@ -56,6 +56,8 @@ void index(const http::server::request &req, http::server::reply &rep, boost::cm html << "
  • /info/lsi/<lsi_name>: show logical switch instance(LSI) information" << std::endl; html << "
  • /info/lsi/<lsi_name>/table/<num>/flows: list LSI table flow entries" << std::endl; html << "
  • /info/lsi/<lsi_name>/group-table: list LSI group table entries" << std::endl; + html << "
  • /info/lsi/<lsi_name>/controllers: list of controllers IDs" << std::endl; + html << "
  • /info/lsi/<lsi_name>/controller/<controller_id>: show controller information" << std::endl; html << "" << std::endl; //POST @@ -75,6 +77,7 @@ void index(const http::server::request &req, http::server::reply &rep, boost::cm html << "
  • /mgmt/create/lsi: create a LSI" << std::endl; html << "
  • /mgmt/create/vlink/<lsi1_name>/<lsi2_name>: create a virtual link between two LSIs" << std::endl; + html << "
  • /mgmt/add/controller/<lsi_name>: add a new controller to an LSI" << std::endl; html << "" << std::endl; @@ -83,6 +86,7 @@ void index(const http::server::request &req, http::server::reply &rep, boost::cm html << "
      " << std::endl; html << "
    • /mgmt/destroy/lsi/<lsi_name>: destroy an LSIs" << std::endl; + html << "
    • /mgmt/remove/controller/<lsi_name>/<controller_id>: remove a controller from LSI" << std::endl; html << "
    " << std::endl; diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index f82653ca..1dad2b80 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -242,9 +242,6 @@ void list_ctls(const http::server::request &req, http::server::reply &rep, boost std::list list; json_spirit::Object table; - //Perform security checks - if(!authorised(req,rep)) return; - lsi_name = std::string(grps[1]); // Get dpid @@ -283,9 +280,6 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: controller_snapshot ctl_info; json_spirit::Object j_wrap, j_ctl, j_list; - //Perform security checks - if(!authorised(req,rep)) return; - lsi_name = std::string(grps[1]); ctl_id = atoi(std::string(grps[2]).c_str()); @@ -328,7 +322,7 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: j_ctl.push_back(json_spirit::Pair("connections", j_list)); //Return data - j_wrap.push_back(json_spirit::Pair("Controller", j_ctl)); + j_wrap.push_back(json_spirit::Pair("controller", j_ctl)); rep.content = json_spirit::write(j_wrap, true); } @@ -531,7 +525,7 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: } //Return assigned ID - table.push_back(json_spirit::Pair("assigned id", assigned_id)); + table.push_back(json_spirit::Pair("controller-id", assigned_id)); rep.content = json_spirit::write(table, true); } diff --git a/src/xdpd/management/plugins/rest/xcli b/src/xdpd/management/plugins/rest/xcli index 82eebc6e..dde0de97 100755 --- a/src/xdpd/management/plugins/rest/xcli +++ b/src/xdpd/management/plugins/rest/xcli @@ -345,7 +345,10 @@ def execute(socket, command, req_confirm=False): if len(stripped) < 5: return "Usage: exec add controller " if "controller" in command: - data = parse_add_controller(stripped[4:]) + try: + data = parse_add_controller(stripped[4:]) + except Exception as e: + return "error: "+str(e) try: return rest(socket, compose_url(stripped[:4]), data, "PUT") except Exception as e: From 95ad31bb7fa90cbea4678ab4f1899c8ba025bcde Mon Sep 17 00:00:00 2001 From: Victor Alvarez Date: Wed, 29 Jul 2015 14:55:06 +0200 Subject: [PATCH 19/19] Fixed indentation and removed unnecessary try/catches --- .../management/plugins/rest/sw-controllers.cc | 57 +++++++------------ src/xdpd/management/plugins/rest/xcli | 10 ++-- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/src/xdpd/management/plugins/rest/sw-controllers.cc b/src/xdpd/management/plugins/rest/sw-controllers.cc index 1dad2b80..6f4bda47 100644 --- a/src/xdpd/management/plugins/rest/sw-controllers.cc +++ b/src/xdpd/management/plugins/rest/sw-controllers.cc @@ -296,11 +296,7 @@ void show_ctl(const http::server::request &req, http::server::reply &rep, boost: dpid = switch_manager::get_switch_dpid(lsi_name); - try{ - switch_manager::get_controller_info(dpid, ctl_id, ctl_info); - }catch(...){ - throw "Unable to get Controller info for lsi"; - } + switch_manager::get_controller_info(dpid, ctl_id, ctl_info); j_ctl.push_back(json_spirit::Pair("id", ctl_info.id)); j_ctl.push_back(json_spirit::Pair("channel-status", ctl_info.get_status_str())); @@ -461,19 +457,19 @@ void add_ctl(const http::server::request &req, http::server::reply &rep, boost:: uint64_t assigned_id; //Perform security checks - if(!authorised(req,rep)) return; + if(!authorised(req,rep)) return; std::string lsi_name = std::string(grps[1]); //Check if LSI exists; - if(!switch_manager::exists_by_name(lsi_name)){ - //Throw 404 - std::stringstream ss; - ss<<"Invalid lsi '"< " + return "Usage: exec remove controller " if "controller" in command: - return rest(socket, compose_url(stripped), data, "DELETE") - else: - return "Usage: exec remove controller " + return rest(socket, compose_url(stripped), data, "DELETE") + else: + return "Usage: exec remove controller " else: return rest(socket, compose_url(stripped), "", "POST") @@ -471,7 +471,7 @@ class InteractivePrompt(cmd.Cmd): if s == "": print "Invalid empty target name" return - if len(s.split()) < 2: + if len(s.split()) < 2: print "Invalid number of parameters." return target = s.split()[0]