Skip to content

Commit

Permalink
Mac route in agent was having invalid label and destination NH.
Browse files Browse the repository at this point in the history
Problem:
Two issues were seen -
1) Label was wrongly interpreted as MPLS though it was VXLAN and never got
corrected. Sequence of events was that EVPN route was received before global
vrouter config. Encapsulation priorities was absent in agent, so evpn route
was programmed with Mpls-gre(control-node had sent Vxlan). Since Mpls encap
was chosen, label was interpreted as mpls label and not vxlan. When global
vrouter config was received resync was done for route. Resync also failed to
rectify encap to Vxlan(since vxlan is now available in priorities) because this
decision to rectify is based on vxlan id(i.e. if vxlan id is 0 default to mpls
                                         as its invalid). In this case vxlan id
was 0 as explained above and hence encap continued to be Mpls.

2) Nexthop was different between evpn route and derived mac route.
This happened because in path sync of evpn route return was false even though NH
change was seen which resulted in avoidance of mac route rebake. Return was
false because value set by ChangeNh as true was overridden by MplsChange.

Solution:
For case 1) - If encap is Vxlan only in the message sent by control-node then
put label as vxlan id and mpls label as invalid, even though tunnel type is
computed as Mpls(encapsulation prioirties is not received). In case of Mpls
encap sent use label as Mpls and reset vxlan to invalid. In case both Vxlan and
Mpls are sent in encap then fallback to old approach of interpreting label on
computed tunnel type.

For case 2) - Fix the return value.

Change-Id: Ibeeb3de16d618ecb931c35d8937591d9c9f7f15e
Closes-bug: 1457355
  • Loading branch information
manishsing committed May 22, 2015
1 parent f514603 commit f8f09e3
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 11 deletions.
34 changes: 24 additions & 10 deletions src/vnsw/agent/controller/controller_route_path.cc
Expand Up @@ -169,17 +169,31 @@ bool ControllerVmRoute::AddChangePath(Agent *agent, AgentPath *path,
ret = true;
}

if (new_tunnel_type == TunnelType::VXLAN) {
if (path->vxlan_id() != label_) {
path->set_vxlan_id(label_);
path->set_label(MplsTable::kInvalidLabel);
ret = true;
}
//Interpret label sent by control node
if (tunnel_bmap_ == TunnelType::VxlanType()) {
//Only VXLAN encap is sent, so label is VXLAN
path->set_vxlan_id(label_);
path->set_label(MplsTable::kInvalidLabel);
} else if (tunnel_bmap_ == TunnelType::MplsType()) {
//MPLS (GRE/UDP) is the only encap sent,
//so label is MPLS.
path->set_label(label_);
path->set_vxlan_id(VxLanTable::kInvalidvxlan_id);
} else {
if (path->label() != label_) {
path->set_label(label_);
path->set_vxlan_id(VxLanTable::kInvalidvxlan_id);
ret = true;
//Got a mix of Vxlan and Mpls, so interpret label
//as per the computed tunnel type.
if (new_tunnel_type == TunnelType::VXLAN) {
if (path->vxlan_id() != label_) {
path->set_vxlan_id(label_);
path->set_label(MplsTable::kInvalidLabel);
ret = true;
}
} else {
if (path->label() != label_) {
path->set_label(label_);
path->set_vxlan_id(VxLanTable::kInvalidvxlan_id);
ret = true;
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/vnsw/agent/oper/agent_path.cc
Expand Up @@ -100,7 +100,8 @@ bool AgentPath::ChangeNH(Agent *agent, NextHop *nh) {
MplsLabelKey key(MplsLabel::MCAST_NH, label_);
MplsLabel *mpls = static_cast<MplsLabel *>(agent->mpls_table()->
FindActiveEntry(&key));
ret = agent->mpls_table()->ChangeNH(mpls, nh);
if (agent->mpls_table()->ChangeNH(mpls, nh))
ret = true;
if (mpls) {
//Send notify of change
mpls->get_table_partition()->Notify(mpls);
Expand Down Expand Up @@ -360,6 +361,7 @@ bool EvpnDerivedPathData::AddChangePath(Agent *agent, AgentPath *path,
EvpnDerivedPath *evpn_path = dynamic_cast<EvpnDerivedPath *>(path);
assert(evpn_path != NULL);

evpn_path->set_server_ip(reference_path_->server_ip());
uint32_t label = reference_path_->label();
if (evpn_path->label() != label) {
evpn_path->set_label(label);
Expand Down
35 changes: 35 additions & 0 deletions src/vnsw/agent/test/test_l2route.cc
Expand Up @@ -615,6 +615,41 @@ TEST_F(RouteTest, vxlan_network_id_change_for_non_l2_interface) {
client->WaitForIdle();
}

TEST_F(RouteTest, RemoteVxlanEncapRoute_1) {
client->Reset();
VxLanNetworkIdentifierMode(false);
client->WaitForIdle();
RouteTest::SetTunnelType(TunnelType::MPLS_GRE);
DelEncapList();
client->WaitForIdle();

TunnelType::TypeBmap bmap = TunnelType::VxlanType();
AddRemoteVmRoute(remote_vm_mac_, remote_vm_ip4_, server1_ip_,
MplsTable::kStartLabel, bmap);
WAIT_FOR(1000, 100,
(L2RouteFind(vrf_name_, remote_vm_mac_, remote_vm_ip4_) == true));

BridgeRouteEntry *rt = L2RouteGet(vrf_name_, remote_vm_mac_,
remote_vm_ip4_);
const AgentPath *path = rt->GetActivePath();
EXPECT_TRUE(path->tunnel_type() != TunnelType::VXLAN);

//Update VXLAN in encap prio
AddEncapList("MPLSoGRE", "MPLSoUDP", "VXLAN");
client->WaitForIdle();
path = rt->GetActivePath();
EXPECT_TRUE(path->tunnel_type() == TunnelType::VXLAN);
const TunnelNH *nh =
static_cast<const TunnelNH *>(path->nexthop());
EXPECT_TRUE(nh->GetDip()->to_string() == server1_ip_.to_string());

DeleteRoute(agent_->local_peer(), vrf_name_, remote_vm_mac_,
remote_vm_ip4_);
client->WaitForIdle();
DelEncapList();
client->WaitForIdle();
}

TEST_F(RouteTest, Enqueue_l2_route_add_on_deleted_vrf) {
struct PortInfo input[] = {
{"vnet1", 1, "1.1.1.10", "00:00:00:01:01:01", 1, 1},
Expand Down

0 comments on commit f8f09e3

Please sign in to comment.