Skip to content

Commit

Permalink
* Read vrouter object limits from vrouter kernel module
Browse files Browse the repository at this point in the history
1> VRouter has a object vrouter_ops which specifies limit
   for individual object entries, changes are made to read
   the same and display it using agent introspect.
2> Removed unnecessary index table operation in ksync for
   mpls and vxlan object.
3> MPLS label space is dynamically allocated based on number
   of VN vrouter supports. If label space is smaller then
   4k label are reserved for VM interfaces and remaining label
   gets equally split between 2 control nodes
Test case to check for multicast label algorithm
Closes-bug:#1456582
Change-Id: I2df821cd6f5c72ad73b229a24884132223f1ac30
  • Loading branch information
naveen-n committed May 27, 2015
1 parent 8ef64c9 commit 61a036f
Show file tree
Hide file tree
Showing 21 changed files with 290 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/ksync/ksync_sock.h
Expand Up @@ -48,6 +48,7 @@ class AgentSandeshContext : public SandeshContext {
virtual void VrfStatsMsgHandler(vr_vrf_stats_req *req) = 0;
virtual void DropStatsMsgHandler(vr_drop_stats_req *req) = 0;
virtual void VxLanMsgHandler(vr_vxlan_req *req) = 0;
virtual void VrouterOpsMsgHandler(vrouter_ops *req) = 0;

void SetErrno(int err) {errno_ = err;};
int GetErrno() const {return errno_;};
Expand Down
37 changes: 29 additions & 8 deletions src/ksync/ksync_sock_user.cc
Expand Up @@ -44,10 +44,6 @@ vr_flow_entry *KSyncSockTypeMap::flow_table_;
int KSyncSockTypeMap::error_code_;
using namespace boost::asio;

//store ops data
void vrouter_ops_test::Process(SandeshContext *context) {
}

//process sandesh messages that are being sent from the agent
//this is used to store a local copy of what is being send to kernel
void KSyncSockTypeMap::ProcessSandesh(const uint8_t *parse_buf, size_t buf_len,
Expand Down Expand Up @@ -168,6 +164,11 @@ void KSyncSockTypeMap::SetDropStats(const vr_drop_stats_req &req) {
sock->drop_stats = req;
}

void KSyncSockTypeMap::SetVRouterOps(const vrouter_ops &req) {
KSyncSockTypeMap *sock = KSyncSockTypeMap::GetKSyncSockTypeMap();
sock->ksync_vrouter_ops = req;
}

void KSyncSockTypeMap::InterfaceAdd(int id, int flags, int mac_size) {
KSyncSockTypeMap *sock = KSyncSockTypeMap::GetKSyncSockTypeMap();
KSyncSockTypeMap::ksync_map_if::const_iterator it;
Expand Down Expand Up @@ -619,10 +620,6 @@ void KSyncSockTypeMap::Init(boost::asio::io_service &ios, int count) {
singleton_->sock_.bind(singleton_->local_ep_);
singleton_->local_ep_ = singleton_->sock_.local_endpoint();

//update map for Sandesh callback of Process()
SandeshBaseFactory::map_type update_map;
update_map["vrouter_ops"] = &createT<vrouter_ops_test>;
SandeshBaseFactory::Update(update_map);
for (int i = 0; i < count; i++) {
KSyncSock::SetSockTableEntry(i, singleton_);
}
Expand Down Expand Up @@ -899,6 +896,21 @@ void KSyncUserSockContext::VxLanMsgHandler(vr_vxlan_req *req) {
SetResponseReqd(false);
}

void KSyncUserSockContext::VrouterOpsMsgHandler(vrouter_ops *req) {
KSyncSockTypeMap *sock = KSyncSockTypeMap::GetKSyncSockTypeMap();
KSyncUserVrouterOpsContext *vrouter_ops =
new KSyncUserVrouterOpsContext(GetSeqNum(), req);

if (sock->IsBlockMsgProcessing()) {
tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
sock->ctx_queue_.push(vrouter_ops);
} else {
vrouter_ops->Process();
delete vrouter_ops;
}
SetResponseReqd(false);
}

void KSyncUserSockVxLanContext::Process() {
KSyncSockTypeMap *sock = KSyncSockTypeMap::GetKSyncSockTypeMap();

Expand Down Expand Up @@ -1487,3 +1499,12 @@ Sandesh* VxLanDumpHandler::GetNext(Sandesh *input) {
return NULL;
}

void KSyncUserVrouterOpsContext::Process() {
KSyncSockTypeMap *sock = KSyncSockTypeMap::GetKSyncSockTypeMap();
if (req_->get_h_op() == sandesh_op::GET) {
VRouterOpsDumpHandler dump;
sock->ksync_vrouter_ops.set_vo_mpls_labels(10000);
dump.SendGetResponse(GetSeqNum(), 0);
return;
}
}
38 changes: 38 additions & 0 deletions src/ksync/ksync_sock_user.h
Expand Up @@ -47,6 +47,7 @@ class KSyncUserSockContext : public AgentSandeshContext {
virtual void VrfStatsMsgHandler(vr_vrf_stats_req *req);
virtual void DropStatsMsgHandler(vr_drop_stats_req *req);
virtual void VxLanMsgHandler(vr_vxlan_req *req);
virtual void VrouterOpsMsgHandler(vrouter_ops *req);
virtual void Process() {}
private:
bool response_reqd_;
Expand Down Expand Up @@ -117,6 +118,7 @@ class KSyncSockTypeMap : public KSyncSock {
typedef std::map<int, vr_vrf_stats_req> ksync_map_vrf_stats;
ksync_map_vrf_stats vrf_stats_map;
vr_drop_stats_req drop_stats;
vrouter_ops ksync_vrouter_ops;
typedef std::map<int, vr_vxlan_req> ksync_map_vxlan;
ksync_map_vxlan vxlan_map;

Expand Down Expand Up @@ -170,6 +172,7 @@ class KSyncSockTypeMap : public KSyncSock {
static void VxlanDelete(int id);

static void SetDropStats(const vr_drop_stats_req &req);
static void SetVRouterOps(const vrouter_ops &req);
static int IfCount();
static int NHCount();
static int MplsCount();
Expand Down Expand Up @@ -307,6 +310,18 @@ class DropStatsDumpHandler : public MockDumpHandlerBase {
}
};

class VRouterOpsDumpHandler : public MockDumpHandlerBase {
public:
VRouterOpsDumpHandler() : MockDumpHandlerBase() {}
virtual Sandesh* GetFirst(Sandesh *) { return NULL;}
virtual Sandesh* GetNext(Sandesh *) { return NULL;}
virtual Sandesh* Get(int idx) {
KSyncSockTypeMap *sock = KSyncSockTypeMap::GetKSyncSockTypeMap();
return &sock->ksync_vrouter_ops;
}
};


class KSyncUserSockIfContext : public KSyncUserSockContext {
public:
KSyncUserSockIfContext(uint32_t seq_num, vr_interface_req *req) : KSyncUserSockContext(false, seq_num) {
Expand Down Expand Up @@ -497,4 +512,27 @@ class KSyncUserSockDropStatsContext : public KSyncUserSockContext {
vr_drop_stats_req *req_;
};

class KSyncUserVrouterOpsContext : public KSyncUserSockContext {
public:
KSyncUserVrouterOpsContext(uint32_t seq_num, vrouter_ops *req) :
KSyncUserSockContext(false, seq_num) {
if (req) {
req_ = new vrouter_ops(*req);
} else {
req_ = NULL;
}
}
~KSyncUserVrouterOpsContext() {
if (req_) {
delete req_;
req_ = NULL;
}
}

virtual void Process();
private:
vrouter_ops *req_;
};


#endif // ctrlplane_ksync_sock_user_h
2 changes: 0 additions & 2 deletions src/vnsw/agent/cmn/agent.cc
Expand Up @@ -217,12 +217,10 @@ void Agent::CopyConfig(AgentParam *params) {
int dns_count = 0;

if (params_->xmpp_server_1().to_ulong()) {
SetAgentMcastLabelRange(count);
xs_addr_[count++] = params_->xmpp_server_1().to_string();
}

if (params_->xmpp_server_2().to_ulong()) {
SetAgentMcastLabelRange(count);
xs_addr_[count++] = params_->xmpp_server_2().to_string();
}

Expand Down
100 changes: 96 additions & 4 deletions src/vnsw/agent/cmn/agent.h
Expand Up @@ -182,6 +182,7 @@ extern void RouterIdDepInit(Agent *agent);
#define MULTICAST_LABEL_RANGE_START 1024
#define MULTICAST_LABEL_BLOCK_SIZE 2048

#define MIN_UNICAST_LABEL_RANGE 4098
#define MAX_XMPP_SERVERS 2
#define XMPP_SERVER_PORT 5269
#define DISCOVERY_SERVER_PORT 5998
Expand Down Expand Up @@ -566,13 +567,31 @@ class Agent {
}
void SetAgentMcastLabelRange(uint8_t idx) {
std::stringstream str;
str << (MULTICAST_LABEL_RANGE_START +
(idx * MULTICAST_LABEL_BLOCK_SIZE)) << "-"
<< (MULTICAST_LABEL_RANGE_START +
((idx + 1) * MULTICAST_LABEL_BLOCK_SIZE) - 1);
//Logic for multicast label allocation
// 1> Reserve minimum 4k label for unicast
// 2> In the remaining label space
// * Try allocating labels equal to no. of VN
// for each control node
// * If label space is not huge enough
// split remaining unicast label for both control
// node
// Remaining label would be used for unicast mpls label
uint32_t max_mc_labels = 2 * vrouter_max_vrfs_;
uint32_t mc_label_count = 0;
if (max_mc_labels + MIN_UNICAST_LABEL_RANGE < vrouter_max_labels_) {
mc_label_count = vrouter_max_vrfs_;
} else {
mc_label_count = (vrouter_max_labels_ - MIN_UNICAST_LABEL_RANGE)/2;
}

str << (vrouter_max_labels_ -
((idx + 1) * mc_label_count)) << "-"
<< (vrouter_max_labels_ -
((idx) * mc_label_count) - 1);
label_range_[idx] = str.str();
}
void ResetAgentMcastLabelRange(uint8_t idx) {

label_range_[idx].clear();
}

Expand Down Expand Up @@ -823,6 +842,65 @@ class Agent {

// Default concurrency checker. Checks for "Agent::KSync" and "db::DBTable"
void ConcurrencyCheck();

uint32_t vrouter_max_labels() const {
return vrouter_max_labels_;
}
void set_vrouter_max_labels(uint32_t max_labels) {
vrouter_max_labels_ = max_labels;
}

uint32_t vrouter_max_nexthops() const {
return vrouter_max_nexthops_;
}
void set_vrouter_max_nexthops(uint32_t max_nexthop) {
vrouter_max_nexthops_ = max_nexthop;
}

uint32_t vrouter_max_interfaces() const {
return vrouter_max_interfaces_;
}
void set_vrouter_max_interfaces(uint32_t max_interfaces) {
vrouter_max_interfaces_ = max_interfaces;
}

uint32_t vrouter_max_vrfs() const {
return vrouter_max_vrfs_;
}
void set_vrouter_max_vrfs(uint32_t max_vrf) {
vrouter_max_vrfs_ = max_vrf;
}

uint32_t vrouter_max_mirror_entries() const {
return vrouter_max_mirror_entries_;
}
void set_vrouter_max_mirror_entries(uint32_t max_mirror_entries) {
vrouter_max_mirror_entries_ = max_mirror_entries;
}


uint32_t vrouter_max_bridge_entries() const {
return vrouter_max_bridge_entries_;
}
void set_vrouter_max_bridge_entries(uint32_t bridge_entries) {
vrouter_max_bridge_entries_ = bridge_entries;
}

uint32_t vrouter_max_oflow_bridge_entries() const {
return vrouter_max_oflow_bridge_entries_;
}
void set_vrouter_max_oflow_bridge_entries(uint32_t
oflow_bridge_entries) {
vrouter_max_oflow_bridge_entries_ = oflow_bridge_entries;
}

void set_vrouter_build_info(std::string version) {
vrouter_build_info_ = version;
}
std::string vrouter_build_info() const {
return vrouter_build_info_;
}

private:

AgentParam *params_;
Expand Down Expand Up @@ -973,6 +1051,20 @@ class Agent {
Ip4Address vrouter_server_ip_;
//TCP port number to be used for sending vrouter sandesh messages
uint32_t vrouter_server_port_;
//Max label space of vrouter
uint32_t vrouter_max_labels_;
//Max nexthop supported by vrouter
uint32_t vrouter_max_nexthops_;
//Max interface supported by vrouter
uint32_t vrouter_max_interfaces_;
//Max VRF supported by vrouter
uint32_t vrouter_max_vrfs_;
//Max Mirror entries
uint32_t vrouter_max_mirror_entries_;
//Bridge entries that can be porgrammed in vrouter
uint32_t vrouter_max_bridge_entries_;
uint32_t vrouter_max_oflow_bridge_entries_;
std::string vrouter_build_info_;

// Constants
static const std::string config_file_;
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/kstate/kstate.h
Expand Up @@ -51,6 +51,7 @@ class KState : public AgentSandeshContext {
virtual void VrfStatsMsgHandler(vr_vrf_stats_req *req);
virtual void DropStatsMsgHandler(vr_drop_stats_req *req);
virtual void VxLanMsgHandler(vr_vxlan_req *req);
virtual void VrouterOpsMsgHandler(vrouter_ops *req) { }
protected:
std::string response_context_;
Sandesh *response_object_;
Expand Down
2 changes: 1 addition & 1 deletion src/vnsw/agent/openstack/instance_service_server.cc
Expand Up @@ -485,7 +485,7 @@ InstanceServiceAsyncHandler::ConvertToUuid(const tuuid &id) {
InstanceServiceAsyncHandler::uuid
InstanceServiceAsyncHandler::MakeUuid(int id) {
char str[50];
sprintf(str, "00000000-0000-0000-0000-0000000000%02x", id);
sprintf(str, "00000000-0000-0000-0000-00%010x", id);
boost::uuids::uuid u1 = StringToUuid(std::string(str));

return u1;
Expand Down
18 changes: 18 additions & 0 deletions src/vnsw/agent/oper/agent.sandesh
Expand Up @@ -1214,3 +1214,21 @@ struct PhysicalDeviceVnObjectLogInfo {
objectlog sandesh PhysicalDeviceVnObjectLog {
1: PhysicalDeviceVnObjectLogInfo port;
}

struct VrouterObjectLimits {
1: i32 max_labels;
2: i32 max_nexthops;
3: i32 max_interfaces;
4: i32 max_vrfs;
5: i32 max_mirror_entries;
6: i32 vrouter_max_bridge_entries;
7: i32 vrouter_max_oflow_bridge_entries;
8: string vrouter_build_info;
}

request sandesh VrouterObjectLimitsReq {
}

response sandesh VrouterObjectLimitsResp {
1: VrouterObjectLimits vrouter_object_limit;
}
19 changes: 19 additions & 0 deletions src/vnsw/agent/oper/agent_sandesh.cc
Expand Up @@ -765,3 +765,22 @@ void AgentInitStateReq::HandleRequest() const {
}
resp->Response();
}

void VrouterObjectLimitsReq::HandleRequest() const {
VrouterObjectLimitsResp *resp = new VrouterObjectLimitsResp();
resp->set_context(context());

Agent *agent = Agent::GetInstance();
VrouterObjectLimits vr_limits;
vr_limits.set_max_labels(agent->vrouter_max_labels());
vr_limits.set_max_nexthops(agent->vrouter_max_nexthops());
vr_limits.set_max_interfaces(agent->vrouter_max_interfaces());
vr_limits.set_max_vrfs(agent->vrouter_max_vrfs());
vr_limits.set_max_mirror_entries(agent->vrouter_max_mirror_entries());
vr_limits.set_vrouter_max_bridge_entries(agent->vrouter_max_bridge_entries());
vr_limits.set_vrouter_max_oflow_bridge_entries(agent->
vrouter_max_oflow_bridge_entries());
vr_limits.set_vrouter_build_info(agent->vrouter_build_info());
resp->set_vrouter_object_limit(vr_limits);
resp->Response();
}
1 change: 1 addition & 0 deletions src/vnsw/agent/oper/interface.cc
Expand Up @@ -139,6 +139,7 @@ DBEntry *InterfaceTable::OperDBAdd(const DBRequest *req) {
intf->GetOsParams(agent());

intf->Add();

intf->SendTrace(Interface::ADD);
return intf;
}
Expand Down

0 comments on commit 61a036f

Please sign in to comment.