Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
BGP as a service agent changes.
Function:
When a VM tries to establish BGP session it will connect o its gateway or DNS
ip. For example in subnet of 1.1.1.0/24, VM will try to connect on well defined
BGP port to either 1.1.1.1(=gw) or 1.1.1.2(=DNS). Agent sees this traffic and
creates a NAT. The calculation of NAT is done as follows:
Pkt from VM:
source: VM-SIP, destination: DIP(gw/dns), source port: VM-sport, destination
port: BGP-port.

After NAT:
source: vrouter IP, destination: Control-node#1(if DIP was gw),
Control-node#2(if DIP was DNS), source port: BGP-router port,
destination port: BGP-port.

Config object(bgp-router) will provide BGP-router port used in NAT.
If new set of control-node changes flows should use new set given.

In this feature agent implements following:
- Add dependency between VM interface, BGP as service.
- BGP as a service node resides under VmInterface. Using adjacencies it travels
to bgp-as-a-service to extract IP for SNAT and bgp-router (adjacent
to for source port nat.
- Flow - Keeping track of bgp-as-a-service object in VMI to populate
flow.
For destination it uses control-node for destination IP.
- Control-node - rebake all Vm interfaces to reflect changes.
- ifmap - white-listing of nodes bgp-as-a-service, vmi, bgp-router.
- Reserves a set of BGP port which can potentially be used in
bgp-router object.
This is provided via contrail-vrouter-agent.conf and agents binds on
to these ports, so that host does not use it.

Pending items:
- UT.

Closes-Bug: 1518047

Conflicts:
	src/ifmap/ifmap_graph_walker.cc
	src/vnsw/agent/oper/agent.sandesh
	src/vnsw/agent/pkt/pkt_flow_info.h

Change-Id: I12c8d019b4b6805cc5517ad595f4d2c8e9956100
  • Loading branch information
manishsing committed Jan 11, 2016
1 parent bd40bd8 commit b515dbf
Show file tree
Hide file tree
Showing 27 changed files with 1,155 additions and 69 deletions.
7 changes: 7 additions & 0 deletions src/ifmap/ifmap_graph_walker.cc
Expand Up @@ -371,6 +371,7 @@ void IFMapGraphWalker::AddNodesToWhitelist() {
traversal_white_list_->include_vertex.insert("loadbalancer-healthmonitor");
traversal_white_list_->include_vertex.insert("subnet");
traversal_white_list_->include_vertex.insert("service-health-check");
traversal_white_list_->include_vertex.insert("bgp-as-a-service");
}

void IFMapGraphWalker::AddLinksToWhitelist() {
Expand Down Expand Up @@ -476,5 +477,11 @@ void IFMapGraphWalker::AddLinksToWhitelist() {
"source=floating-ip-pool,target=virtual-network");
traversal_white_list_->include_edge.insert(
"source=virtual-machine-interface,target=service-health-check");
traversal_white_list_->include_edge.insert(
"source=virtual-machine-interface,target=bgp-as-a-service");
traversal_white_list_->include_edge.insert(
"source=bgp-as-a-service,target=bgp-router");
traversal_white_list_->include_edge.insert(
"source=bgp-router,target=routing-instance");
}

4 changes: 4 additions & 0 deletions src/vnsw/agent/contrail-vrouter-agent.conf
Expand Up @@ -199,3 +199,7 @@ docker_command=/usr/bin/opencontrail-vrouter-docker
#
# Log message if time taken to schedule task exceeds a threshold (in msec)
# log_schedule_threshold = 25

[SERVICES]
# bgp_as_a_service_port_range - reserving set of ports to be used.
# bgp_as_a_service_port_range=30000-35000
10 changes: 7 additions & 3 deletions src/vnsw/agent/controller/controller_init.cc
Expand Up @@ -47,7 +47,7 @@ VNController::VNController(Agent *agent)
work_queue_(agent->task_scheduler()->GetTaskId("Agent::ControllerXmpp"), 0,
boost::bind(&VNController::ControllerWorkQueueProcess, this,
_1)),
fabric_multicast_label_range_() {
fabric_multicast_label_range_(), xmpp_channel_down_cb_() {
work_queue_.set_name("Controller Queue");
decommissioned_peer_list_.clear();
}
Expand Down Expand Up @@ -302,7 +302,8 @@ void VNController::DnsXmppServerDisConnect() {
//If not agent never got a channel down state and is being removed
//as it is not part of discovery list.
//Artificially inject NOT_READY in agent xmpp channel.
void VNController::DeleteAgentXmppChannel(AgentXmppChannel *channel) {
void VNController::DeleteAgentXmppChannel(uint8_t idx) {
AgentXmppChannel *channel = agent_->controller_xmpp_channel(idx);
if (!channel)
return;

Expand All @@ -315,6 +316,9 @@ void VNController::DeleteAgentXmppChannel(AgentXmppChannel *channel) {
AgentXmppChannel::HandleAgentXmppClientChannelEvent(channel,
xmps::NOT_READY);
}
//Every delete of channel should delete flow of bgp-as-a-service,
//which is using this CN.
xmpp_channel_down_cb_(idx);
}

//Trigger shutdown and cleanup of routes for the client
Expand Down Expand Up @@ -386,7 +390,7 @@ void VNController::DisConnectControllerIfmapServer(uint8_t idx) {
agent_->set_controller_ifmap_xmpp_client(NULL, idx);

//cleanup AgentXmppChannel
DeleteAgentXmppChannel(agent_->controller_xmpp_channel(idx));
DeleteAgentXmppChannel(idx);
agent_->reset_controller_xmpp_channel(idx);

//cleanup AgentIfmapXmppChannel
Expand Down
7 changes: 6 additions & 1 deletion src/vnsw/agent/controller/controller_init.h
Expand Up @@ -77,6 +77,7 @@ class ControllerDiscoveryData : public ControllerWorkQueueData {

class VNController {
public:
typedef boost::function<void(uint8_t)> XmppChannelDownCb;
typedef boost::shared_ptr<ControllerXmppData> ControllerXmppDataType;
typedef boost::shared_ptr<ControllerDeletePeerData> ControllerDeletePeerDataType;
typedef boost::shared_ptr<ControllerWorkQueueData> ControllerWorkQueueDataType;
Expand Down Expand Up @@ -154,14 +155,17 @@ class VNController {
bool XmppMessageProcess(ControllerXmppDataType data);
Agent *agent() {return agent_;}
void Enqueue(ControllerWorkQueueDataType data);
void DeleteAgentXmppChannel(AgentXmppChannel *ch);
void DeleteAgentXmppChannel(uint8_t idx);
void SetAgentMcastLabelRange(uint8_t idx);
void FillMcastLabelRange(uint32_t *star_idx,
uint32_t *end_idx,
uint8_t idx) const;
const FabricMulticastLabelRange &fabric_multicast_label_range(uint8_t idx) const {
return fabric_multicast_label_range_[idx];
}
void RegisterControllerChangeCallback(XmppChannelDownCb xmpp_channel_down_cb) {
xmpp_channel_down_cb_ = xmpp_channel_down_cb;
}

private:
AgentXmppChannel *FindAgentXmppChannel(const std::string &server_ip);
Expand All @@ -181,6 +185,7 @@ class VNController {
ConfigCleanupTimer config_cleanup_timer_;
WorkQueue<ControllerWorkQueueDataType> work_queue_;
FabricMulticastLabelRange fabric_multicast_label_range_[MAX_XMPP_SERVERS];
XmppChannelDownCb xmpp_channel_down_cb_;
};

extern SandeshTraceBufferPtr ControllerInfoTraceBuf;
Expand Down
14 changes: 14 additions & 0 deletions src/vnsw/agent/init/agent_param.cc
Expand Up @@ -577,6 +577,11 @@ void AgentParam::ParseNexthopServer() {
}
}

void AgentParam::ParseBgpAsAServicePortRange() {
GetValueFromTree<string>(bgp_as_a_service_port_range_,
"SERVICES.bgp_as_a_service_port_range");
}

void AgentParam::ParseCollectorArguments
(const boost::program_options::variables_map &var_map) {
GetOptValue< vector<string> >(var_map, collector_server_list_,
Expand Down Expand Up @@ -792,6 +797,12 @@ void AgentParam::ParsePlatformArguments
}
}

void AgentParam::ParseBgpAsAServicePortRangeArguments
(const boost::program_options::variables_map &v) {
GetOptValue<string>(v, bgp_as_a_service_port_range_,
"SERVICES.bgp_as_a_service_port_range");
}

// Initialize hypervisor mode based on system information
// If "/proc/xen" exists it means we are running in Xen dom0
void AgentParam::InitFromSystem() {
Expand Down Expand Up @@ -840,6 +851,7 @@ void AgentParam::InitFromConfig() {
ParseAgentInfo();
ParseNexthopServer();
ParsePlatform();
ParseBgpAsAServicePortRange();
cout << "Config file <" << config_file_ << "> parsing completed.\n";
return;
}
Expand All @@ -863,6 +875,7 @@ void AgentParam::InitFromArguments() {
ParseAgentInfoArguments(var_map_);
ParseNexthopServerArguments(var_map_);
ParsePlatformArguments(var_map_);
ParseBgpAsAServicePortRangeArguments(var_map_);
return;
}

Expand Down Expand Up @@ -1085,6 +1098,7 @@ void AgentParam::LogConfig() const {
LOG(DEBUG, "Service instance workers : " << si_netns_workers_);
LOG(DEBUG, "Service instance timeout : " << si_netns_timeout_);
LOG(DEBUG, "Service instance lb ssl : " << si_lb_ssl_cert_path_);
LOG(DEBUG, "Bgp as a service port range : " << bgp_as_a_service_port_range_);
if (hypervisor_mode_ == MODE_KVM) {
LOG(DEBUG, "Hypervisor mode : kvm");
return;
Expand Down
8 changes: 8 additions & 0 deletions src/vnsw/agent/init/agent_param.h
Expand Up @@ -225,13 +225,17 @@ class AgentParam {
}
std::string agent_base_dir() const { return agent_base_dir_; }
uint32_t sandesh_send_rate_limit() { return send_ratelimit_; }
const std::string &bgp_as_a_service_port_range() const {
return bgp_as_a_service_port_range_;
}

uint16_t flow_thread_count() const { return flow_thread_count_; }
void set_flow_thread_count(uint16_t count) { flow_thread_count_ = count; }

uint32_t tbb_thread_count() const { return tbb_thread_count_; }
uint32_t tbb_exec_delay() const { return tbb_exec_delay_; }
uint32_t tbb_schedule_delay() const { return tbb_schedule_delay_; }

protected:
void set_hypervisor_mode(HypervisorMode m) { hypervisor_mode_ = m; }
virtual void InitFromSystem();
Expand Down Expand Up @@ -305,6 +309,7 @@ class AgentParam {
void ParseAgentInfo();
void ParseNexthopServer();
void ParsePlatform();
void ParseBgpAsAServicePortRange();
void set_agent_mode(const std::string &mode);

void ParseCollectorArguments
Expand Down Expand Up @@ -337,6 +342,8 @@ class AgentParam {
(const boost::program_options::variables_map &v);
void ParsePlatformArguments
(const boost::program_options::variables_map &v);
void ParseBgpAsAServicePortRangeArguments
(const boost::program_options::variables_map &v);

boost::program_options::variables_map var_map_;
boost::program_options::options_description options_;
Expand Down Expand Up @@ -427,6 +434,7 @@ class AgentParam {
uint32_t send_ratelimit_;
uint16_t flow_thread_count_;
bool subnet_hosts_resolvable_;
std::string bgp_as_a_service_port_range_;

// TBB related
uint32_t tbb_thread_count_;
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/oper/SConscript
Expand Up @@ -33,6 +33,7 @@ vnswoperdb = env.Library('vnswoperdb',
'agent_route.cc',
'agent_route_resync.cc',
'agent_route_walker.cc',
'bgp_as_service.cc',
'bridge_route.cc',
'config_manager.cc',
'evpn_route.cc',
Expand Down
16 changes: 16 additions & 0 deletions src/vnsw/agent/oper/agent.sandesh
Expand Up @@ -1364,3 +1364,19 @@ response sandesh HealthCheckSandeshResp {
1: list<HealthCheckSandeshData> hc_list;
}

struct BgpAsAServiceSandeshList {
1: string vm_bgp_peer_ip;
2: i32 vm_nat_source_port;
3: string vmi_uuid (link="ItfReq"); // intf uuid
}

request sandesh BgpAsAServiceSandeshReq {
}

response sandesh BgpAsAServiceSandeshResp {
1: list<BgpAsAServiceSandeshList> bgp_as_a_service_list;
}

trace sandesh BgpAsAServiceTrace {
1: string message;
}
50 changes: 50 additions & 0 deletions src/vnsw/agent/oper/audit_list.h
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
*/

#ifndef vnsw_agent_audit_list_hpp
#define vnsw_agent_audit_list_hpp

/////////////////////////////////////////////////////////////////////////////
// Template function to audit two lists. This is used to synchronize the
// operational and config list for Floating-IP, Service-Vlans, Static Routes
// and SG List
/////////////////////////////////////////////////////////////////////////////
template<class List, class Iterator>
bool AuditList(List &list, Iterator old_first, Iterator old_last,
Iterator new_first, Iterator new_last) {
bool ret = false;
Iterator old_iterator = old_first;
Iterator new_iterator = new_first;
while (old_iterator != old_last && new_iterator != new_last) {
if (old_iterator->IsLess(new_iterator.operator->())) {
Iterator bkp = old_iterator++;
list.Remove(bkp);
ret = true;
} else if (new_iterator->IsLess(old_iterator.operator->())) {
Iterator bkp = new_iterator++;
list.Insert(bkp.operator->());
ret = true;
} else {
Iterator old_bkp = old_iterator++;
Iterator new_bkp = new_iterator++;
list.Update(old_bkp.operator->(), new_bkp.operator->());
ret = true;
}
}

while (old_iterator != old_last) {
Iterator bkp = old_iterator++;
list.Remove(bkp);
ret = true;
}

while (new_iterator != new_last) {
Iterator bkp = new_iterator++;
list.Insert(bkp.operator->());
ret = true;
}

return ret;
}
#endif

0 comments on commit b515dbf

Please sign in to comment.