Skip to content

Commit

Permalink
Agent changes to support unknown unicast flooding
Browse files Browse the repository at this point in the history
* VMI would have a flag to specify whether unknown unicast
  packet should be flooded.
* VXLAN NH also would have similar flag to specify unknown unicast
  to be flooded or not.
* For ingress traffic, unknown unicast flow would have policy
  applied based on ingress route, once layer2 route is added
  flow would be reevaluated again.
  Test cases for same.
Closes-Bug: #1424523

Change-Id: I327202f384df24f48ad7c7f32181d564f6ff105a
(cherry picked from commit 6e98f0d)
  • Loading branch information
naveen-n committed May 4, 2015
1 parent b67e240 commit 4c67c94
Show file tree
Hide file tree
Showing 28 changed files with 485 additions and 43 deletions.
3 changes: 3 additions & 0 deletions src/vnsw/agent/oper/agent.sandesh
Expand Up @@ -87,6 +87,7 @@ struct ItfSandeshData {
43: optional string vmi_type;
44: string transport;
45: string logical_interface_uuid;
46: optional bool flood_unknown_unicast;
}

struct VnIpamData {
Expand Down Expand Up @@ -120,6 +121,7 @@ struct VnSandeshData {
14: i32 vn_id;
15: bool enable_rpf;
16: bool bridging;
17: bool flood_unknown_unicast;
}

struct SgSandeshData {
Expand Down Expand Up @@ -213,6 +215,7 @@ struct NhSandeshData {
22: optional MulticastCompositeData interface_comp; //Multicast sub nh list
23: optional MulticastCompositeData evpn_comp; //Multicast sub nh list
24: optional bool vxlan_flag;
25: optional bool flood_unknown_unicast;
}

struct NamespaceStateSandeshData {
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/oper/interface.cc
Expand Up @@ -738,6 +738,7 @@ void Interface::SetItfSandeshData(ItfSandeshData &data) const {
} else {
data.set_policy("Disable");
}
data.set_flood_unknown_unicast(vintf->flood_unknown_unicast());

if ((ipv4_active_ == false) ||
(l2_active_ == false)) {
Expand Down
2 changes: 1 addition & 1 deletion src/vnsw/agent/oper/mpls.cc
Expand Up @@ -109,7 +109,7 @@ void MplsTable::CreateTableLabel(const Agent *agent,
nh_req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
VrfNHKey *vrf_nh_key = new VrfNHKey(vrf_name, false, false);
nh_req.key.reset(vrf_nh_key);
nh_req.data.reset(new VrfNHData());
nh_req.data.reset(new VrfNHData(false));
agent->nexthop_table()->Process(nh_req);

DBRequest req;
Expand Down
8 changes: 8 additions & 0 deletions src/vnsw/agent/oper/nexthop.cc
Expand Up @@ -663,6 +663,13 @@ VrfNH::KeyPtr VrfNH::GetDBRequestKey() const {

bool VrfNH::Change(const DBRequest *req) {
bool ret = false;
const VrfNHData *data = static_cast<const VrfNHData *>(req->data.get());

if (data->flood_unknown_unicast_ != flood_unknown_unicast_) {
flood_unknown_unicast_ = data->flood_unknown_unicast_;
ret = true;
}

return ret;
}

Expand Down Expand Up @@ -2257,6 +2264,7 @@ void NextHop::SetNHSandeshData(NhSandeshData &data) const {
const VrfNH *vrf = static_cast<const VrfNH *>(this);
data.set_vrf(vrf->GetVrf()->GetName());
data.set_vxlan_flag(vrf->vxlan_nh());
data.set_flood_unknown_unicast(vrf->flood_unknown_unicast());
break;
}
case INTERFACE: {
Expand Down
14 changes: 10 additions & 4 deletions src/vnsw/agent/oper/nexthop.h
Expand Up @@ -952,17 +952,20 @@ class VrfNHKey : public NextHopKey {

class VrfNHData : public NextHopData {
public:
VrfNHData() : NextHopData() { }
VrfNHData(bool flood_unknown_unicast) : NextHopData(),
flood_unknown_unicast_(flood_unknown_unicast) {}
virtual ~VrfNHData() { }
private:
friend class VrfNH;
bool flood_unknown_unicast_;
DISALLOW_COPY_AND_ASSIGN(VrfNHData);
};

class VrfNH : public NextHop {
public:
VrfNH(VrfEntry *vrf, bool policy, bool vxlan_nh_) :
NextHop(VRF, true, policy), vrf_(vrf), vxlan_nh_(vxlan_nh_) { };
VrfNH(VrfEntry *vrf, bool policy, bool vxlan_nh_):
NextHop(VRF, true, policy), vrf_(vrf), vxlan_nh_(vxlan_nh_),
flood_unknown_unicast_(false) {}
virtual ~VrfNH() { };

virtual std::string ToString() const { return "VrfNH"; };
Expand All @@ -980,11 +983,14 @@ class VrfNH : public NextHop {
return true;
}
bool vxlan_nh() const { return vxlan_nh_; }

bool flood_unknown_unicast() const {
return flood_unknown_unicast_;
}
private:
VrfEntryRef vrf_;
// NH created by VXLAN
bool vxlan_nh_;
bool flood_unknown_unicast_;
DISALLOW_COPY_AND_ASSIGN(VrfNH);
};

Expand Down
13 changes: 11 additions & 2 deletions src/vnsw/agent/oper/vm_interface.cc
Expand Up @@ -55,7 +55,8 @@ VmInterface::VmInterface(const boost::uuids::uuid &uuid) :
need_linklocal_ip_(false), dhcp_enable_(true),
do_dhcp_relay_(false), vm_name_(),
vm_project_uuid_(nil_uuid()), vxlan_id_(0), bridging_(true),
layer3_forwarding_(true), mac_set_(false), ecmp_(false),
layer3_forwarding_(true), flood_unknown_unicast_(false),
mac_set_(false), ecmp_(false),
tx_vlan_id_(kInvalidVlanId), rx_vlan_id_(kInvalidVlanId), parent_(NULL),
local_preference_(VmInterface::INVALID), oper_dhcp_options_(),
sg_list_(), floating_ip_list_(), service_vlan_list_(), static_route_list_(),
Expand Down Expand Up @@ -85,7 +86,8 @@ VmInterface::VmInterface(const boost::uuids::uuid &uuid,
need_linklocal_ip_(false), dhcp_enable_(true),
do_dhcp_relay_(false), vm_name_(vm_name),
vm_project_uuid_(vm_project_uuid), vxlan_id_(0),
bridging_(true), layer3_forwarding_(true), mac_set_(false),
bridging_(true), layer3_forwarding_(true),
flood_unknown_unicast_(false), mac_set_(false),
ecmp_(false), tx_vlan_id_(tx_vlan_id), rx_vlan_id_(rx_vlan_id),
parent_(parent), local_preference_(VmInterface::INVALID), oper_dhcp_options_(),
sg_list_(), floating_ip_list_(), service_vlan_list_(), static_route_list_(),
Expand Down Expand Up @@ -1521,6 +1523,13 @@ bool VmInterface::CopyConfig(const InterfaceTable *table,
vxlan_id_ = vxlan_id;
ret = true;
}

bool flood_unknown_unicast =
vn ? vn->flood_unknown_unicast(): false;
if (flood_unknown_unicast_ != flood_unknown_unicast) {
flood_unknown_unicast_ = flood_unknown_unicast;
ret = true;
}
}

if (local_preference_ != data->local_preference_) {
Expand Down
4 changes: 4 additions & 0 deletions src/vnsw/agent/oper/vm_interface.h
Expand Up @@ -380,6 +380,9 @@ class VmInterface : public Interface {
const boost::uuids::uuid &logical_interface() const {
return logical_interface_;
}
bool flood_unknown_unicast() const {
return flood_unknown_unicast_;
}

Interface::MirrorDirection mirror_direction() const {
return mirror_direction_;
Expand Down Expand Up @@ -655,6 +658,7 @@ class VmInterface : public Interface {
int vxlan_id_;
bool bridging_;
bool layer3_forwarding_;
bool flood_unknown_unicast_;
bool mac_set_;
bool ecmp_;
// VLAN Tag and the parent interface when VLAN is enabled
Expand Down
28 changes: 20 additions & 8 deletions src/vnsw/agent/oper/vn.cc
Expand Up @@ -90,7 +90,7 @@ bool VnIpam::IsSubnetMember(const IpAddress &ip) const {
VnEntry::VnEntry(Agent *agent, uuid id) :
AgentOperDBEntry(), uuid_(id), vxlan_id_(0), vnid_(0),
bridging_(true), layer3_forwarding_(true), admin_state_(true),
table_label_(0), enable_rpf_(true) {
table_label_(0), enable_rpf_(true), flood_unknown_unicast_(false) {
}

VnEntry::~VnEntry() {
Expand Down Expand Up @@ -213,7 +213,7 @@ int VnEntry::ComputeEthernetTag() const {
}

void VnEntry::RebakeVxLan(int vxlan_id) {
VxLanId::Create(vxlan_id, GetVrf()->GetName());
VxLanId::Create(vxlan_id, GetVrf()->GetName(), flood_unknown_unicast_);
VxLanId *vxlan_id_entry = NULL;
VxLanIdKey vxlan_key(vxlan_id);
vxlan_id_entry = static_cast<VxLanId *>(Agent::GetInstance()->
Expand All @@ -223,7 +223,8 @@ void VnEntry::RebakeVxLan(int vxlan_id) {

bool VnEntry::ReEvaluateVxlan(VrfEntry *old_vrf, int new_vxlan_id, int new_vnid,
bool new_bridging,
bool vxlan_network_identifier_mode_changed) {
bool vxlan_network_identifier_mode_changed,
bool new_flood_unknown_unicast) {
bool ret = false;
bool rebake_vxlan = false;

Expand Down Expand Up @@ -264,6 +265,12 @@ bool VnEntry::ReEvaluateVxlan(VrfEntry *old_vrf, int new_vxlan_id, int new_vnid,
vnid_ = new_vnid;
ret = true;
}

if (flood_unknown_unicast_ != new_flood_unknown_unicast) {
flood_unknown_unicast_ = new_flood_unknown_unicast;
rebake_vxlan = true;
ret = true;
}
}

if (!GetVrf()) {
Expand All @@ -286,7 +293,7 @@ bool VnEntry::ReEvaluateVxlan(VrfEntry *old_vrf, int new_vxlan_id, int new_vnid,
bool VnEntry::VxLanNetworkIdentifierChanged() {
//No change in VN config.
//Need to pick vxlan based on config mode
return ReEvaluateVxlan(NULL, 0, 0, true, true);
return ReEvaluateVxlan(NULL, 0, 0, true, true, flood_unknown_unicast_);
}

bool VnEntry::Resync() {
Expand Down Expand Up @@ -424,7 +431,8 @@ bool VnTable::ChangeHandler(DBEntry *entry, const DBRequest *req) {
}

ret |= vn->ReEvaluateVxlan(old_vrf, data->vxlan_id_, data->vnid_,
data->bridging_, false);
data->bridging_, false,
data->flood_unknown_unicast_);


if (vn->enable_rpf_ != data->enable_rpf_) {
Expand Down Expand Up @@ -631,11 +639,12 @@ VnData *VnTable::BuildData(IFMapNode *node) {
else
network_id = cfg->properties().network_id;

bool flood_unknown_unicast = cfg->flood_unknown_unicast();
return new VnData(agent(), node->name(), acl_uuid, vrf_name, mirror_acl_uuid,
mirror_cfg_acl_uuid, vn_ipam, vn_ipam_data,
cfg->properties().vxlan_network_identifier,
network_id, bridging, layer3_forwarding,
cfg->id_perms().enable, enable_rpf);
cfg->id_perms().enable, enable_rpf, flood_unknown_unicast);
}

// Change to ACL referernce can result in change of Policy flag
Expand Down Expand Up @@ -778,13 +787,15 @@ void VnTable::AddVn(const uuid &vn_uuid, const string &name,
const uuid &acl_id, const string &vrf_name,
const std::vector<VnIpam> &ipam,
const VnData::VnIpamDataMap &vn_ipam_data,
int vxlan_id, bool admin_state, bool enable_rpf) {
int vxlan_id, bool admin_state, bool enable_rpf,
bool flood_unknown_unicast) {
DBRequest req;
VnKey *key = new VnKey(vn_uuid);
VnData *data = new VnData(agent(), name, acl_id, vrf_name, nil_uuid(),
nil_uuid(), ipam, vn_ipam_data,
vxlan_id, vxlan_id, true, true,
admin_state, enable_rpf);
admin_state, enable_rpf,
flood_unknown_unicast);

req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
req.key.reset(key);
Expand Down Expand Up @@ -1083,6 +1094,7 @@ bool VnEntry::DBEntrySandesh(Sandesh *sresp, std::string &name) const {
data.set_bridging(bridging());
data.set_admin_state(admin_state());
data.set_enable_rpf(enable_rpf());
data.set_flood_unknown_unicast(flood_unknown_unicast());

std::vector<VnSandeshData> &list =
const_cast<std::vector<VnSandeshData>&>(resp->get_vn_list());
Expand Down
15 changes: 11 additions & 4 deletions src/vnsw/agent/oper/vn.h
Expand Up @@ -89,13 +89,15 @@ struct VnData : public AgentOperDBData {
const string &vrf_name, const uuid &mirror_acl_id, const uuid &mc_acl_id,
const std::vector<VnIpam> &ipam, const VnIpamDataMap &vn_ipam_data,
int vxlan_id, int vnid, bool bridging,
bool layer3_forwarding, bool admin_state, bool enable_rpf) :
bool layer3_forwarding, bool admin_state, bool enable_rpf,
bool flood_unknown_unicast) :
AgentOperDBData(agent, NULL), name_(name), vrf_name_(vrf_name),
acl_id_(acl_id), mirror_acl_id_(mirror_acl_id),
mirror_cfg_acl_id_(mc_acl_id), ipam_(ipam), vn_ipam_data_(vn_ipam_data),
vxlan_id_(vxlan_id), vnid_(vnid), bridging_(bridging),
layer3_forwarding_(layer3_forwarding), admin_state_(admin_state),
enable_rpf_(enable_rpf) {
enable_rpf_(enable_rpf),
flood_unknown_unicast_(flood_unknown_unicast) {
};
virtual ~VnData() { }

Expand All @@ -112,6 +114,7 @@ struct VnData : public AgentOperDBData {
bool layer3_forwarding_;
bool admin_state_;
bool enable_rpf_;
bool flood_unknown_unicast_;
};

class VnEntry : AgentRefCount<VnEntry>, public AgentOperDBEntry {
Expand Down Expand Up @@ -152,7 +155,8 @@ class VnEntry : AgentRefCount<VnEntry>, public AgentOperDBEntry {
bool VxLanNetworkIdentifierChanged();
bool ReEvaluateVxlan(VrfEntry *old_vrf, int new_vxlan_id, int new_vnid,
bool new_bridging,
bool vxlan_network_identifier_mode_changed);
bool vxlan_network_identifier_mode_changed,
bool new_flood_unknown_unicast);
void UpdateMacVmBindingFloodFlag();

const VxLanId *vxlan_id_ref() const {return vxlan_id_ref_.get();}
Expand All @@ -161,6 +165,7 @@ class VnEntry : AgentRefCount<VnEntry>, public AgentOperDBEntry {
bool layer3_forwarding() const {return layer3_forwarding_;};
bool admin_state() const {return admin_state_;}
bool enable_rpf() const {return enable_rpf_;}
bool flood_unknown_unicast() const {return flood_unknown_unicast_;}

AgentDBTable *DBToTable() const;
uint32_t GetRefCount() const {
Expand Down Expand Up @@ -190,6 +195,7 @@ class VnEntry : AgentRefCount<VnEntry>, public AgentOperDBEntry {
VxLanIdRef vxlan_id_ref_;
uint32_t table_label_;
bool enable_rpf_;
bool flood_unknown_unicast_;
DISALLOW_COPY_AND_ASSIGN(VnEntry);
};

Expand Down Expand Up @@ -223,7 +229,8 @@ class VnTable : public AgentOperDBTable {
void AddVn(const uuid &vn_uuid, const string &name, const uuid &acl_id,
const string &vrf_name, const std::vector<VnIpam> &ipam,
const VnData::VnIpamDataMap &vn_ipam_data, int vxlan_id,
bool admin_state, bool enable_rpf);
bool admin_state, bool enable_rpf,
bool flood_unknown_unicast);
void DelVn(const uuid &vn_uuid);
VnEntry *Find(const uuid &vn_uuid);
void UpdateVxLanNetworkIdentifierMode();
Expand Down
5 changes: 3 additions & 2 deletions src/vnsw/agent/oper/vxlan.cc
Expand Up @@ -104,12 +104,13 @@ DBTableBase *VxLanTable::CreateTable(DB *db, const std::string &name) {
return vxlan_id_table_;
}

void VxLanId::Create(uint32_t vxlan_id, const string &vrf_name) {
void VxLanId::Create(uint32_t vxlan_id, const string &vrf_name,
bool flood_unknown_unicast) {
DBRequest nh_req;
nh_req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
VrfNHKey *vrf_nh_key = new VrfNHKey(vrf_name, false, true);
nh_req.key.reset(vrf_nh_key);
nh_req.data.reset(new VrfNHData());
nh_req.data.reset(new VrfNHData(flood_unknown_unicast));

DBRequest req;
req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/oper/vxlan.h
Expand Up @@ -28,7 +28,8 @@ class VxLanId : AgentRefCount<VxLanId>, public AgentDBEntry {
uint32_t vxlan_id() const {return vxlan_id_;};
const NextHop *nexthop() const {return nh_.get();};

static void Create(uint32_t vxlan_id, const std::string &vrf_name);
static void Create(uint32_t vxlan_id, const std::string &vrf_name,
bool flood_unknown_unicast);
// Delete vxlan_id vxlan_id entry
static void Delete(uint32_t vxlan_id);

Expand Down
2 changes: 2 additions & 0 deletions src/vnsw/agent/pkt/flow_handler.cc
Expand Up @@ -43,6 +43,8 @@ bool FlowHandler::Run() {
pkt_info_->agent_hdr.vrf = fe->data().vrf;
pkt_info_->family =
fe->key().src_addr.is_v4() ? Address::INET : Address::INET6;
pkt_info_->smac = fe->data().smac;
pkt_info_->dmac = fe->data().dmac;
pkt_info_->ip_saddr = fe->key().src_addr;
pkt_info_->ip_daddr = fe->key().dst_addr;
pkt_info_->ip_proto = fe->key().protocol;
Expand Down

0 comments on commit 4c67c94

Please sign in to comment.