Skip to content

Commit

Permalink
Issue # 13 : switch description exported via cli
Browse files Browse the repository at this point in the history
  • Loading branch information
dipjyoti committed Feb 26, 2015
1 parent 95c08f2 commit f151ed8
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 3 deletions.
40 changes: 40 additions & 0 deletions application/cli/mul_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,45 @@ DEFUN (of_switch_table_stats_show,
return CMD_SUCCESS;
}


DEFUN (show_of_switch_desc_detail,
show_of_switch_desc_detail_cmd,
"show of-switch X desc-features",
SHOW_STR
"Openflow switches\n"
"Datapath-id in 0xXXX format\n"
"Switch description features\n")
{
uint64_t dp_id;
struct cbuf *b;
char * pbuf;

dp_id = strtoull(argv[0], NULL, 16);

vty_out (vty,
"-------------------------------------------"
"----------------------------------%s",
VTY_NEWLINE);


b = mul_get_switch_features(cli->mul_service, dp_id,
0, C_AUX_CMD_MUL_GET_SWITCH_DESC);
if (b) {
pbuf = mul_dump_switch_desc(b, true);
if (pbuf) {
vty_out (vty, "%s", pbuf);
free(pbuf);
}
}

vty_out (vty,
"-------------------------------------------"
"----------------------------------%s%s",
VTY_NEWLINE, VTY_NEWLINE);

return CMD_SUCCESS;
}

DEFUN (show_of_switch_group_detail,
show_of_switch_group_detail_cmd,
"show of-switch X group-features",
Expand Down Expand Up @@ -6160,6 +6199,7 @@ cli_module_vty_init(void *arg)
//install_element(MUL_NODE, &mul_conf_exit_cmd);
install_element(ENABLE_NODE, &show_of_switch_cmd);
install_element(ENABLE_NODE, &show_of_switch_detail_cmd);
install_element(ENABLE_NODE, &show_of_switch_desc_detail_cmd);
install_element(ENABLE_NODE, &show_of_switch_group_detail_cmd);
install_element(ENABLE_NODE, &show_of_switch_meter_detail_cmd);
install_element(ENABLE_NODE, &show_of_switch_table_detail_cmd);
Expand Down
1 change: 1 addition & 0 deletions common-libs/mul-lib/include/mul_app_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ struct c_ofp_auxapp_cmd {
#define C_AUX_CMD_MUL_GET_MATCHED_GROUP (C_AUX_CMD_MUL_CORE_BASE + 25)
#define C_AUX_CMD_MUL_GET_MATCHED_METER (C_AUX_CMD_MUL_CORE_BASE + 26)
#define C_AUX_CMD_MUL_MOD_UFLOW (C_AUX_CMD_MUL_CORE_BASE + 27)
#define C_AUX_CMD_MUL_GET_SWITCH_DESC (C_AUX_CMD_MUL_CORE_BASE + 28)

#define C_AUX_CMD_TR_BASE (C_AUX_CMD_MUL_CORE_BASE + 1000)
#define C_AUX_CMD_TR_GET_NEIGH (C_AUX_CMD_TR_BASE + 1)
Expand Down
2 changes: 2 additions & 0 deletions common-libs/mul-lib/include/mul_of_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,8 @@ struct c_ofp_ctors {
bool acts_only, void *u_arg);
};
typedef struct c_ofp_ctors c_ofp_ctors_t;

char *of_switch_desc_dump(void *desc, size_t desc_len);
void of_mact_alloc(mul_act_mdata_t *mdata);
void of_mact_free(mul_act_mdata_t *mdata);
void of_capabilities_tostr(char *string, uint32_t capabilities);
Expand Down
1 change: 1 addition & 0 deletions common-libs/mul-lib/include/mul_servlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ int mul_get_meter_info(void *service, uint64_t dpid,
void (*cb_fn)(void *arg, void *pbuf));
struct cbuf * mul_get_switch_features(void *service, uint64_t dpid,
uint8_t table, uint32_t type);
char *mul_dump_switch_desc(struct cbuf *b, bool free_buf);
char *mul_dump_switch_meter_features(struct cbuf *b, bool free_buf);
char *mul_dump_switch_group_features(struct cbuf *b, bool free_buf);
char *mul_dump_switch_table_features(struct cbuf *b, bool free_buf);
Expand Down
49 changes: 47 additions & 2 deletions common-libs/mul-lib/src/mul_of_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,53 @@ of_capabilities_tostr(char *string, uint32_t capabilities)
}
}

char *
of_switch_desc_dump(void *desc, size_t desc_len)
{
char *pbuf;
size_t len = 0;
struct ofp_desc_stats *ofp_d = desc;

if (desc_len != sizeof(*ofp_d)) {
c_log_err("%s: Can't dump size err", FN);
return NULL;
}
pbuf = calloc(1, OF_DUMP_MSG_SZ);
assert(pbuf);

len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%-20s", "Manufacturer:");
ofp_d->mfr_desc[DESC_STR_LEN-1] = '\0';
len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%s\r\n", ofp_d->mfr_desc);

len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%-20s", "HW Desc:");
ofp_d->hw_desc[DESC_STR_LEN-1] = '\0';
len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%s\r\n", ofp_d->hw_desc);

len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%-20s", "SW Desc:");
ofp_d->sw_desc[DESC_STR_LEN-1] = '\0';
len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%s\r\n", ofp_d->sw_desc);

len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%-20s", "Serial:");
ofp_d->sw_desc[SERIAL_NUM_LEN-1] = '\0';
len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%s\r\n", ofp_d->serial_num);

len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%-20s", "DP Desc:");
ofp_d->dp_desc[DESC_STR_LEN-1] = '\0';
len += snprintf(pbuf + len, OF_DUMP_MSG_SZ - len - 1,
"%s\r\n", ofp_d->dp_desc);

return pbuf;
}

bool
of_switch_supports_flow_stats(uint32_t cap)
{
Expand Down Expand Up @@ -7599,8 +7646,6 @@ of131_act_type_to_name(uint16_t act)
return "";
}



char *
of131_group_features_dump(void *feat, size_t feat_len)
{
Expand Down
34 changes: 34 additions & 0 deletions mul/mul_app_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -2670,6 +2670,37 @@ c_app_rcv_ha_sync_req(void *app_arg UNUSED, struct cbuf *b)
c_switch_put(sw);
}

static void
c_app_send_switch_desc(void *app_arg, struct cbuf *b)
{
struct c_ofp_auxapp_cmd *cofp_aac = CBUF_DATA(b);
struct c_ofp_switch_feature_common *cofp_f;
c_switch_t *sw = NULL;

if (ntohs(cofp_aac->header.length) <
sizeof(*cofp_aac) + sizeof(*cofp_f)) {
c_log_err("%s: Size err (%x) of (%lx)", FN,
ntohs(cofp_aac->header.length),
U322UL(sizeof(*cofp_aac) + sizeof(*cofp_f)));
c_remote_app_error(app_arg, b, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
return;
}

cofp_f = ASSIGN_PTR(cofp_aac->data);
sw = c_switch_get(&ctrl_hdl, ntohll(cofp_f->datapath_id));
if (!sw) {
c_log_err("%s: Switch(0x%llx) not found", FN, U642ULL(ntohll(cofp_f->datapath_id)));
c_remote_app_error(app_arg, b, OFPET_BAD_REQUEST, OFPBRC_BAD_DPID);
return;
}

b = c_of_prep_switch_desc_msg(sw);
c_switch_put(sw);
c_remote_app_event(app_arg, b);

return;
}

static void
c_app_send_switch_group_features(void *app_arg, struct cbuf *b)
{
Expand Down Expand Up @@ -3446,6 +3477,9 @@ c_app_aux_request_handler(void *app_arg, struct cbuf *b, void *data)
case C_AUX_CMD_HA_SYNC_DONE:
c_app_rcv_ha_sync_done(app_arg, b);
break;
case C_AUX_CMD_MUL_GET_SWITCH_DESC:
c_app_send_switch_desc(app_arg, b);
break;
case C_AUX_CMD_MUL_SWITCH_GROUP_FEAT:
c_app_send_switch_group_features(app_arg, b);
break;
Expand Down
56 changes: 56 additions & 0 deletions mul/mul_of.c
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,7 @@ c_switch_put(c_switch_t *sw)
c_sw_exp_ent_free);
if (sw->meter_features) free(sw->meter_features);
if (sw->group_features) free(sw->group_features);
if (sw->sw_desc) free(sw->sw_desc);
if (sw->sw_ports) g_hash_table_destroy(sw->sw_ports);
if (sw->groups) g_hash_table_destroy(sw->groups);
if (sw->meters) g_hash_table_destroy(sw->meters);
Expand Down Expand Up @@ -961,6 +962,8 @@ c_switch_try_publish(c_switch_t *sw, bool need_ha_sync_req)
__of_send_mpart_msg(sw, OFPMP_METER_FEATURES, 0, 0);
/* There is no port info in features reply. Get it! */
__of_send_mpart_msg(sw, OFPMP_PORT_DESC, 0, 0);
/* Get switch description */
__of_send_mpart_msg(sw, OFPMP_DESC, 0, 0);
sw->last_feat_probed = ctime;
c_log_debug("|SWITCH| Port Probe for |0x%llx|",
U642ULL(sw->DPID));
Expand Down Expand Up @@ -2466,6 +2469,34 @@ c_of_fl_group_check_add(void *sw_arg, uint32_t group_id, void *arg)
return true;
}

struct cbuf *
c_of_prep_switch_desc_msg(c_switch_t *sw)
{
struct cbuf *b;
size_t tot_len = 0;
struct c_ofp_auxapp_cmd *cofp_aac;
struct c_ofp_switch_feature_common *cofp_sfc;

c_rd_lock(&sw->lock);
tot_len = sizeof(*cofp_sfc) + sizeof(*cofp_aac) +
((sw->sw_desc) ? sw->desc_len : 0);

b = of_prep_msg(tot_len, C_OFPT_AUX_CMD, 0);

cofp_aac = CBUF_DATA(b);
cofp_aac->cmd_code = htonl(C_AUX_CMD_MUL_GET_SWITCH_DESC);

cofp_sfc = ASSIGN_PTR(cofp_aac->data);
cofp_sfc->datapath_id = htonll(sw->DPID);
if (sw->sw_desc) {
memcpy(cofp_sfc->data, sw->sw_desc, sw->desc_len);
}

c_rd_unlock(&sw->lock);

return b;
}

struct cbuf *
c_of_prep_group_feature_msg(c_switch_t *sw)
{
Expand Down Expand Up @@ -6680,6 +6711,9 @@ of131_recv_features_reply(c_switch_t *sw, struct cbuf *b)
/* Update gen-id if stale */
c_switch_tx(sw, of131_prep_role_request_msg(OFPCR_ROLE_NOCHANGE, 0), false);

/* Update switch description */
c_switch_tx(sw, of131_prep_mpart_msg(OFPMP_DESC, 0, 0), false);

sw->last_feat_probed = time(NULL);
}

Expand Down Expand Up @@ -6784,6 +6818,25 @@ of13_14_mpart_process(c_switch_t *sw, struct cbuf *b)
}

switch (htons(ofp_mr->type)) {
case OFPMP_DESC:
{
struct ofp_desc_stats *ofp_d = (void *)(ofp_mr->body);

if (body_len < sizeof(*ofp_d)) break;

if (!sw->sw_desc ||
sw->desc_len != sizeof(*ofp_d)) {
if (sw->sw_desc) free(sw->sw_desc);
sw->sw_desc = calloc(1, sizeof(*ofp_d));
if (!sw->sw_desc) break;
}
c_wr_lock(&sw->lock);
c_log_err("%s Recevied DESC Reply", FN);
memcpy(sw->sw_desc, ofp_d, sizeof(*ofp_d));
sw->desc_len = sizeof(*ofp_d);
c_wr_unlock(&sw->lock);
break;
}
case OFPMP_PORT_DESC:
{
struct ofp131_port *port = (void *)(ofp_mr->body);
Expand Down Expand Up @@ -7880,6 +7933,9 @@ of140_recv_features_reply(c_switch_t *sw, struct cbuf *b)
/* Update gen-id if stale */
c_switch_tx(sw, of140_prep_role_request_msg(OFPCR_ROLE_NOCHANGE, 0), false);

/* Update switch description */
c_switch_tx(sw, of140_prep_mpart_msg(OFPMP_DESC, 0, 0), false);

sw->last_feat_probed = time(NULL);
}

Expand Down
1 change: 1 addition & 0 deletions mul/mul_of.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ bool c_of_fl_group_check_add(void *sw_arg, uint32_t group_id, void *a
struct cbuf * c_of_prep_group_mod_msg(c_switch_group_t *grp, bool add);
bool c_of_fl_meter_check_add(void *sw_arg, uint32_t group_id, void *arg);
struct cbuf * c_of_prep_meter_mod_msg(c_switch_meter_t *meter, bool add);
struct cbuf * c_of_prep_switch_desc_msg(c_switch_t *sw);
struct cbuf * c_of_prep_group_feature_msg(c_switch_t *sw);
struct cbuf * c_of_prep_meter_feature_msg(c_switch_t *sw);
struct cbuf * c_of_prep_table_feature_msg(c_switch_t *sw, uint8_t table_id);
Expand Down
2 changes: 2 additions & 0 deletions mul/mul_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ struct c_switch

GSList *exp_list; /* Expired entries */

void *sw_desc; /* Switch description */
size_t desc_len; /* Description length */
void *group_features; /* Group features */
size_t group_feat_len; /* Group features length */
void *meter_features; /* Meter features */
Expand Down
52 changes: 51 additions & 1 deletion mul/mul_servlet.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,8 @@ mul_get_switch_detail_config(void *service, uint64_t dpid, void *arg,
* @param [in] dpid Datapath_id of the requested switch
* @param [in] table table-id if requesting for table features
* @param [in] type Type of feature requested : C_AUX_CMD_MUL_SWITCH_METER_FEAT,
* C_AUX_CMD_MUL_SWITCH_TABLE_FEAT, C_AUX_CMD_MUL_SWITCH_GROUP_FEAT
* C_AUX_CMD_MUL_SWITCH_TABLE_FEAT, C_AUX_CMD_MUL_SWITCH_GROUP_FEAT,
* C_AUX_CMD_MUL_GET_SWITCH_DESC
*
* @retval struct cbuf * Pointer to buffer returned by server
*/
Expand Down Expand Up @@ -496,6 +497,7 @@ mul_get_switch_features(void *service, uint64_t dpid, uint8_t table,
case C_AUX_CMD_MUL_SWITCH_METER_FEAT:
case C_AUX_CMD_MUL_SWITCH_TABLE_FEAT:
case C_AUX_CMD_MUL_SWITCH_GROUP_FEAT:
case C_AUX_CMD_MUL_GET_SWITCH_DESC:
break;
default:
free_cbuf(b);
Expand Down Expand Up @@ -569,6 +571,54 @@ mul_dump_switch_table_features(struct cbuf *b, bool free_buf)
return buf;
}

/**
* @name mul_dump_switch_desc -
* @brief Dump a switch's description
* @param [in] b Pointer to the cbuf response from server
* @param [in] free_buf Flag to denote freeing the buffer
*
* @retval char * Pointer to the ascii string result
*/
char *
mul_dump_switch_desc(struct cbuf *b, bool free_buf)
{
struct c_ofp_auxapp_cmd *cofp_auc;
struct c_ofp_switch_feature_common *cofp_f;
char *buf = NULL;
uint8_t version;

if (!b) return NULL;

cofp_auc = CBUF_DATA(b);
if (cofp_auc->cmd_code != htonl(C_AUX_CMD_MUL_GET_SWITCH_DESC)) {
goto free_out;
}

if (ntohs(cofp_auc->header.length) -
(sizeof(*cofp_auc) + sizeof(*cofp_f)) <
sizeof(struct ofp_desc_stats)) {
c_log_err("%s: Len error", FN);
goto free_out;
}

cofp_f = ASSIGN_PTR(cofp_auc->data);

version = c_app_switch_get_version_with_id(ntohll(cofp_f->datapath_id));
if (version != OFP_VERSION && version != OFP_VERSION_131 &&
version != OFP_VERSION_140) {
c_log_err("%s:Unsupported OFP version", FN);
goto free_out;
}

buf = of_switch_desc_dump(cofp_f->data,
sizeof(struct ofp_desc_stats));
free_out:
if (free_buf) {
free_cbuf(b);
}
return buf;
}

/**
* @name mul_dump_switch_group_features -
* @brief Dump a switch's group features
Expand Down

0 comments on commit f151ed8

Please sign in to comment.