...
 
Commits (2)
......@@ -22,6 +22,13 @@ int transport_client_init(const char* server_ip, uint16_t port) {
return -1;
}
//set timeout for send and recv
struct timeval timeout;
timeout.tv_sec = 2;
timeout.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
......
......@@ -112,6 +112,8 @@ int mcc_install_flow_on_data_sink(cn_node_t *proxy_node, cn_flow_t *flow) {
res = -1;
} else {
res = 0;
memcpy(&flow->flow, &inst_flow, sizeof(inst_flow));
memcpy(&flow->mask, &inst_mask, sizeof(inst_mask));
}
mul_app_act_free(&mdata);
......@@ -125,6 +127,49 @@ int mcc_install_flow_on_data_sink(cn_node_t *proxy_node, cn_flow_t *flow) {
return res;
}
int mcc_remove_flow_on_data_sink(cn_node_t *proxy_node, cn_flow_t *flow) {
c_log_debug("DEBUG:%s:Remove flow rules for data sink node[%s at %d.%d.%d.%d] "
"from data source node[%s at %d.%d.%d.%d]", __func__,
flow->node->id, NetByteOrderIPv4(flow->node->ipv4.addr.s_addr),
proxy_node->id, NetByteOrderIPv4(proxy_node->ipv4.addr.s_addr));
int res = -1;
uint64_t ddpid;
cn_port_t *dcpo;
cn_switch_t *dcsw;
cn_node_t *flow_node;
if (cn_unordered_acquire_flow_switch_lock(flow, &flow_node, &dcpo, &dcsw) != 0) {
cncerr("Couldn't lock flow parents\n");
return -1;
}
ddpid = dcsw->mul_switch->dpid;
struct flow inst_flow = flow->flow;
memcpy(&inst_flow.ip.nw_src, &proxy_node->ipv4.addr.s_addr, sizeof(proxy_node->ipv4.addr.s_addr));
char *flow_str = _flow_rule_str(&inst_flow);
c_log_debug("DEBUG:%s:Flow rule to be deleted[%s]", __func__, flow_str);
free(flow_str);
res = mul_app_send_flow_del(CNC_APP_NAME, NULL, ddpid, &inst_flow,
&flow->mask, OFPP_NONE, C_FL_PRIO_DFL+1, 0,
OFPG_ANY);
if (res != 0) {
cncerr("mul_app_send_flow_del failed with code: %d\n", res);
res = -1;
} else {
res = 0;
}
cn_obj_unlock(flow);
cn_obj_unlock(flow->node);
cn_obj_unlock(dcpo);
cn_obj_unlock(dcsw);
return res;
}
int mcc_install_flow_on_data_source(cn_node_t *src_node, cn_shadow_t *flow_shadow) {
c_log_debug("DEBUG:%s:Install flow rules for data source node[%s at %d.%d.%d.%d]"
......@@ -193,6 +238,8 @@ int mcc_install_flow_on_data_source(cn_node_t *src_node, cn_shadow_t *flow_shado
res = -1;
} else {
res = 0;
memcpy(&flow_shadow->shadow_flow.flow, &inst_flow, sizeof(inst_flow));
memcpy(&flow_shadow->shadow_flow.mask, &inst_mask, sizeof(inst_mask));
}
mul_app_act_free(&mdata);
......@@ -206,3 +253,50 @@ int mcc_install_flow_on_data_source(cn_node_t *src_node, cn_shadow_t *flow_shado
return res;
}
int mcc_remove_flow_on_data_source(cn_node_t *src_node, cn_shadow_t *flow_shadow) {
c_log_debug("DEBUG:%s:Remove flow rules for data source node[%s at %d.%d.%d.%d]"
" to data sink node[%s at %d.%d.%d.%d]", __func__, src_node->id,
NetByteOrderIPv4(src_node->ipv4.addr.s_addr),
flow_shadow->shadow_flow.dst_node_info.id,
NetByteOrderIPv4(flow_shadow->shadow_flow.dst_node_info.ipv4.addr.s_addr) );
int res = -1;
uint64_t sdpid;
cn_port_t *scpo;
cn_switch_t *scsw;
if (cn_unordered_acquire_node_switch_lock(src_node, &scpo, &scsw) != 0) {
cncerr("Couldn't lock src_node\n");
return -1;
}
sdpid = scsw->mul_switch->dpid;
//lock shadow object
cn_obj_lock(flow_shadow);
struct flow inst_flow = flow_shadow->shadow_flow.flow;
//memcpy(&inst_flow.dl_src, src_node->mac, OFP_ETH_ALEN);
char *flow_str = _flow_rule_str(&inst_flow);
c_log_debug("DEBUG:%s:Flow rule to be deleted[%s]", __func__, flow_str);
free(flow_str);
res = mul_app_send_flow_del(CNC_APP_NAME, NULL, sdpid, &inst_flow,
&flow_shadow->shadow_flow.mask, OFPP_NONE, C_FL_PRIO_DFL+1, 0,
OFPG_ANY);
if (res != 0) {
cncerr("mul_app_send_flow_del failed with code: %d\n", res);
res = -1;
} else {
res = 0;
}
cn_obj_unlock(flow_shadow);
cn_obj_unlock(src_node);
cn_obj_unlock(scpo);
cn_obj_unlock(scsw);
return res;
}
......@@ -4,5 +4,8 @@
#include "obj.h"
int mcc_install_flow_on_data_sink(cn_node_t * receiver, cn_flow_t *flow);
int mcc_remove_flow_on_data_sink(cn_node_t *proxy_node, cn_flow_t *flow);
int mcc_install_flow_on_data_source(cn_node_t *src_node, cn_shadow_t *flow_shadow);
int mcc_remove_flow_on_data_source(cn_node_t *src_node, cn_shadow_t *flow_shadow);
#endif
......@@ -247,8 +247,11 @@ int cn_delete_flow_cb(struct cnode *flow_cnode, void * payload) {
}
cncinfo("[flow delete cb] deleteing flow %s -> %s\n", owner->id, flow->node->id);
cnc_remove_flow(owner, flow);
if(owner->obj.is_proxy) {
mcc_remove_flow_on_data_sink(owner, flow);
} else {
cnc_remove_flow(owner, flow);
}
end1:
cn_obj_unlock(flow);
......@@ -315,10 +318,40 @@ int cn_shadow_delete_cb(struct cnode *shadow_cnode, void * payload) {
int ret;
assert(cn_cnode_type(shadow_cnode) == CN_SHADOW
&& "shadow delete callback invoked for non-shadow");
if ((ret = cn_default_delete_cb(shadow_cnode, payload)) != 0) {
return ret;
}
cn_shadow_t *shadow = (cn_shadow_t *) cn_cnode_object(shadow_cnode);
cn_obj_lock(shadow);
switch (shadow->cap_type) {
case CN_FLOW: {
cn_principal_t * principal = cn_cnode_principal(shadow_cnode);
cn_obj_lock(principal);
cn_node_t * owner = (cn_node_t *) principal->owner;
/* No need to worry about flow stuff if the owner is not a node */
if (owner == NULL) { goto end; }
cn_obj_lock(owner);
(void) __entry_decref(owner->remote_node_table, &shadow->shadow_flow.dst_node_obj_id);
bool do_delete = __entry_decref(owner->remote_flow_table, &shadow->obj_id);
if (! do_delete) {
cncinfo("[shadow delete cb] skipping flow delete, not our last capability\n");
cn_obj_unlock(owner);
cn_obj_unlock(principal);
goto finish;
}
cncinfo("[flow delete cb] deleteing flow %s -> %s\n", owner->id, shadow->shadow_flow.dst_node_info.id);
mcc_remove_flow_on_data_source(owner, shadow);
cn_obj_unlock(owner);
cn_obj_unlock(principal);
break;
}
default:;
}
finish:
cn_obj_unlock(shadow);
end:
ret = cn_default_delete_cb(shadow_cnode, payload);
return ret;
}
......