Skip to content

Commit

Permalink
Merge "* Install FIP EVPN routes received from control-node"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Apr 22, 2016
2 parents 6499d15 + 8631919 commit a067a90
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 22 deletions.
26 changes: 10 additions & 16 deletions src/vnsw/agent/controller/controller_peer.cc
Expand Up @@ -907,30 +907,24 @@ void AgentXmppChannel::AddEvpnRoute(const std::string &vrf_name,
return;
}

// We expect only INTERFACE nexthop for evpn routes
const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>(nh);
if (nh->GetType() != NextHop::INTERFACE) {
CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), vrf_name,
"Invalid nexthop in evpn route");
return;
}

//In EVPN, if interface IP is not same as IP received in Evpn route
//then use receive NH. This is done because this received evpn ip is
//a floating IP associated with VM and it shoul be routed.
const VmInterface *vm_intf =
dynamic_cast<const VmInterface *>(intf_nh->
GetInterface());
if (vm_intf) {
if (vm_intf->IsFloatingIp(ip_addr)) {
rt_table->AddReceiveRouteReq(bgp_peer_id(), vrf_name,
if (nh->GetType() == NextHop::L2_RECEIVE) {
rt_table->AddControllerReceiveRouteReq(bgp_peer_id(), vrf_name,
label, mac, ip_addr,
item->entry.nlri.ethernet_tag,
item->entry.virtual_network,
path_preference);
return;
}
return;
}

// We expect only INTERFACE nexthop for evpn routes
const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>(nh);
if (nh->GetType() != NextHop::INTERFACE) {
CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), vrf_name,
"Invalid nexthop in evpn route");
return;
}

SecurityGroupList sg_list = item->entry.security_group_list.security_group;
Expand Down
5 changes: 2 additions & 3 deletions src/vnsw/agent/controller/controller_peer.h
Expand Up @@ -161,7 +161,8 @@ class AgentXmppChannel {
bool associate,
const AgentPath *path,
bool assisted_replication);

void AddEvpnRoute(const std::string &vrf_name, std::string mac_addr,
autogen::EnetItemType *item);
protected:
virtual void WriteReadyCb(const boost::system::error_code &ec);

Expand All @@ -174,8 +175,6 @@ class AgentXmppChannel {
void AddMulticastEvpnRoute(const std::string &vrf_name,
const MacAddress &mac,
autogen::EnetItemType *item);
void AddEvpnRoute(const std::string &vrf_name, std::string mac_addr,
autogen::EnetItemType *item);
void AddRemoteRoute(std::string vrf_name, IpAddress ip, uint32_t plen,
autogen::ItemType *item,
const VnListType &vn_list);
Expand Down
15 changes: 15 additions & 0 deletions src/vnsw/agent/controller/controller_route_path.cc
Expand Up @@ -441,3 +441,18 @@ string ControllerMulticastRoute::PeerInvalidMsg
bool ControllerMulticastRoute::IsPeerValid(const AgentRouteKey *key) const {
return CheckPeerValidity(channel_, sequence_number_);
}

ControllerL2ReceiveRoute::ControllerL2ReceiveRoute(const std::string &vn_name,
uint32_t vxlan_id,
uint32_t mpls_label,
const PathPreference
&path_preference,
uint64_t sequence_number,
const AgentXmppChannel
*channel):
L2ReceiveRoute(vn_name, vxlan_id, mpls_label, path_preference),
sequence_number_(sequence_number), channel_(channel) { }

bool ControllerL2ReceiveRoute::IsPeerValid(const AgentRouteKey *key) const {
return CheckPeerValidity(channel_, sequence_number_);
}
17 changes: 16 additions & 1 deletion src/vnsw/agent/controller/controller_route_path.h
Expand Up @@ -265,6 +265,22 @@ class ClonedLocalPath : public AgentRouteData {
DISALLOW_COPY_AND_ASSIGN(ClonedLocalPath);
};

class ControllerL2ReceiveRoute : public L2ReceiveRoute {
public:
ControllerL2ReceiveRoute(const std::string &dest_vn_name, uint32_t vxlan_id,
uint32_t mpls_label,
const PathPreference &path_preference,
uint64_t sequence_number,
const AgentXmppChannel *channel);
virtual ~ControllerL2ReceiveRoute() { }
virtual bool IsPeerValid(const AgentRouteKey *key) const;

private:
uint64_t sequence_number_;
const AgentXmppChannel *channel_;
DISALLOW_COPY_AND_ASSIGN(ControllerL2ReceiveRoute);
};

class ControllerMulticastRoute : public MulticastRoute {
public:
ControllerMulticastRoute(const string &vn_name,
Expand All @@ -284,5 +300,4 @@ class ControllerMulticastRoute : public MulticastRoute {
const AgentXmppChannel *channel_;
DISALLOW_COPY_AND_ASSIGN(ControllerMulticastRoute);
};

#endif //controller_route_path_hpp
12 changes: 11 additions & 1 deletion src/vnsw/agent/oper/agent_path.cc
Expand Up @@ -526,11 +526,21 @@ bool L2ReceiveRoute::AddChangePath(Agent *agent, AgentPath *path,
ret = true;
}

if (path->peer() && path->peer()->GetType() == Peer::BGP_PEER) {
//Copy entire path preference for BGP peer path,
//since allowed-address pair config doesn't modify
//preference on BGP path
if (path->path_preference() != path_preference_) {
path->set_path_preference(path_preference_);
ret = true;
}
}

if (path->ChangeNH(agent, agent->nexthop_table()->l2_receive_nh()) == true)
ret = true;

return ret;
}
}

bool InetInterfaceRoute::UpdateRoute(AgentRoute *rt) {
bool ret = false;
Expand Down
23 changes: 23 additions & 0 deletions src/vnsw/agent/oper/evpn_route.cc
Expand Up @@ -15,6 +15,7 @@
#include <oper/mirror_table.h>
#include <controller/controller_export.h>
#include <controller/controller_peer.h>
#include <controller/controller_route_path.h>
#include <oper/agent_sandesh.h>
#include <pkt/pkt_init.h>
#include <pkt/pkt_handler.h>
Expand Down Expand Up @@ -147,6 +148,28 @@ void EvpnAgentRouteTable::AddOvsPeerMulticastRouteReq(const Peer *peer,
AddOvsPeerMulticastRouteInternal(peer, vxlan_id, vn_name, tsn, tor_ip, true);
}

void EvpnAgentRouteTable::AddControllerReceiveRouteReq(const Peer *peer,
const string &vrf_name,
uint32_t label,
const MacAddress &mac,
const IpAddress &ip_addr,
uint32_t ethernet_tag,
const string &vn_name,
const PathPreference &path_pref) {
const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer *>(peer);
assert(bgp_peer != NULL);

DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
ethernet_tag));
req.data.reset(new ControllerL2ReceiveRoute(vn_name, ethernet_tag,
label, path_pref,
bgp_peer->GetBgpXmppPeerConst()->
unicast_sequence_number(),
bgp_peer->GetBgpXmppPeerConst()));
agent()->fabric_evpn_table()->Enqueue(&req);
}

void EvpnAgentRouteTable::AddReceiveRouteReq(const Peer *peer,
const string &vrf_name,
uint32_t label,
Expand Down
6 changes: 6 additions & 0 deletions src/vnsw/agent/oper/evpn_route.h
Expand Up @@ -47,6 +47,12 @@ class EvpnAgentRouteTable : public AgentRouteTable {
const IpAddress &ip_addr, uint32_t ethernet_tag,
const std::string &vn_name,
const PathPreference &pref);
void AddControllerReceiveRouteReq(const Peer *peer,
const std::string &vrf_name,
uint32_t label, const MacAddress &mac,
const IpAddress &ip_addr, uint32_t ethernet_tag,
const std::string &vn_name,
const PathPreference &pref);
void AddLocalVmRouteReq(const Peer *peer,
const std::string &vrf_name,
const MacAddress &mac,
Expand Down
68 changes: 67 additions & 1 deletion src/vnsw/agent/test/test_route.cc
Expand Up @@ -31,7 +31,7 @@
#include "test_cmn_util.h"
#include "kstate/test/test_kstate_util.h"
#include "vr_types.h"

#include "net/bgp_af.h"
#include <controller/controller_export.h>

using namespace boost::assign;
Expand Down Expand Up @@ -2285,6 +2285,72 @@ TEST_F(RouteTest, EcmpTest_1) {
client->WaitForIdle();
}

TEST_F(RouteTest, fip_evpn_route_local) {
struct PortInfo input[] = {
{"vnet1", 1, "1.1.1.10", "00:00:01:01:01:10", 1, 1},
};

client->Reset();
//Creation
CreateVmportFIpEnv(input, 1);
client->WaitForIdle();
//Create floating IP pool
AddFloatingIpPool("fip-pool1", 1);
AddFloatingIp("fip1", 1, "2.2.2.10");
AddLink("floating-ip", "fip1", "floating-ip-pool", "fip-pool1");
AddLink("floating-ip-pool", "fip-pool1", "virtual-network",
"default-project:vn1");

//Associate vnet1 with floating IP
AddLink("virtual-machine-interface", "vnet1", "floating-ip", "fip1");
client->WaitForIdle();

//Add a peer
BgpPeer *bgp_peer_ptr = CreateBgpPeer(Ip4Address(1), "BGP Peer1");
boost::shared_ptr<BgpPeer> bgp_peer =
bgp_peer_ptr->GetBgpXmppPeer()->bgp_peer_id_ref();
client->WaitForIdle();

//Search our evpn route
EvpnRouteEntry *rt = EvpnRouteGet("default-project:vn1:vn1",
MacAddress::FromString(input[0].mac),
Ip4Address::from_string("2.2.2.10"), 0);
EXPECT_TRUE(rt != NULL);
AgentPath *path = rt->FindLocalVmPortPath();
EXPECT_TRUE(path != NULL);
EXPECT_TRUE(rt->GetActivePath() == path);
EXPECT_TRUE(rt->GetActiveNextHop()->GetType() == NextHop::L2_RECEIVE);

//Reflect CN route and see if its added.
stringstream ss_node;
autogen::EnetItemType item;
SecurityGroupList sg;

item.entry.nlri.af = BgpAf::L2Vpn;
item.entry.nlri.safi = BgpAf::Enet;
item.entry.nlri.address="2.2.2.10/32";
item.entry.nlri.ethernet_tag = 0;
autogen::EnetNextHopType nh;
nh.af = Address::INET;
nh.address = agent_->router_ip_ptr()->to_string();
nh.label = rt->GetActiveLabel();
item.entry.next_hops.next_hop.push_back(nh);
item.entry.med = 0;


bgp_peer_ptr->GetBgpXmppPeer()->AddEvpnRoute("default-project:vn1:vn1",
"00:00:01:01:01:10",
&item);
client->WaitForIdle();
EXPECT_TRUE(rt->GetActivePath() != path);

client->WaitForIdle();
DeleteVmportFIpEnv(input, 1, true);
client->WaitForIdle();
DeleteBgpPeer(bgp_peer.get());
client->WaitForIdle();
}

int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
GETUSERARGS();
Expand Down

0 comments on commit a067a90

Please sign in to comment.