Skip to content

Commit

Permalink
Mirroring function will be enhanced with the following options:
Browse files Browse the repository at this point in the history
1. Knob to control addition of Juniper header
This nob is to control the mirror packet with or without Juniper
header
2. Knob to control if the Nexthop used is dynamic or static.
if this nob is by default enabled for dynamic if static is choosen
then config needs to be updated with Vtep VNI details
Config points to Dynamic without Juniper header
------------------------------------------------
config provides mirror_vrf if the Vrfentry is present based on remote vm mac
bridge entry lookup is done and if it is present the active nexthop & label
pointed will be attached to mirror entry

Vrfentry is not present oper entry will be created that downloads
the control-node route information if the active next hop is preset attach it to
mirror entry otherwise point to Discard entry.

Config points to Static without Juniper header
----------------------------------------------
Config provides Vtep destination IP & VNI details if the active nexthop points
to TunnelNH of type vxlan, attach it to Mirror entry otherwise create new
tunnel NH with vtep dst ip of type VXLAN and attach it to mirror entry.

Change-Id: Ib6c4af21b5807f9bf57b83728fcd4ea4106add57
Partial-Bug: #1592049
  • Loading branch information
jayaramsatya committed Jul 14, 2016
1 parent 40b1919 commit 73aa175
Show file tree
Hide file tree
Showing 11 changed files with 746 additions and 34 deletions.
78 changes: 66 additions & 12 deletions src/vnsw/agent/cfg/cfg_mirror.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,36 @@ const char *MirrorCfgTable::Add(const MirrorCreateReq &cfg) {
return "Invalid mirror destination port ";
}

IpAddress sip = agent_cfg_->agent()->GetMirrorSourceIp(dest_ip);

MirrorTable::AddMirrorEntry(entry->key.handle,
entry->data.mirror_vrf, sip,
agent_cfg_->agent()->mirror_port(),
dest_ip, entry->data.udp_port);
IpAddress sip = agent_cfg_->agent()->GetMirrorSourceIp(dest_ip);
MirrorEntryData::MirrorEntryFlags mirror_flag =
MirrorTable::DecodeMirrorFlag(cfg.get_nhmode(),
cfg.get_juniperheader());
if (mirror_flag == MirrorEntryData::DynamicNH_With_JuniperHdr) {
MirrorTable::AddMirrorEntry(entry->key.handle,
entry->data.mirror_vrf, sip,
agent_cfg_->agent()->mirror_port(),
dest_ip, entry->data.udp_port);
} else if (mirror_flag == MirrorEntryData::DynamicNH_Without_JuniperHdr) {
MacAddress mac = MacAddress::FromString(cfg.get_analyzer_vm_mac());
MirrorTable::AddMirrorEntry(entry->key.handle,entry->data.mirror_vrf,
sip, agent_cfg_->agent()->mirror_port(),
dest_ip, entry->data.udp_port, 0,
mirror_flag, mac);
} else if (mirror_flag == MirrorEntryData::StaticNH_Without_JuniperHdr) {

IpAddress dst_ip = IpAddress::from_string(cfg.get_vtep_dst_ip(), ec);
if (ec.value() != 0) {
delete entry;
return "Invalid mirror destination address ";
}
MirrorTable::AddMirrorEntry(entry->key.handle, entry->data.mirror_vrf,
sip, agent_cfg_->agent()->mirror_port(),
dst_ip, entry->data.udp_port,
cfg.get_vni(), mirror_flag,
MacAddress::ZeroMac());
} else {
return "Mode not supported";
}

// Update ACL
VnAclMap::iterator va_it;
Expand Down Expand Up @@ -432,12 +456,42 @@ const char *IntfMirrorCfgTable::Add(const IntfMirrorCreateReq &intf_mirror) {
entry->data.mirror_dest.time_period = intf_mirror.get_time_period();
entry->data.mirror_dest.mirror_vrf = intf_mirror.get_mirror_vrf();

MirrorTable::AddMirrorEntry(entry->key.handle,
entry->data.mirror_dest.mirror_vrf,
entry->data.mirror_dest.sip,
entry->data.mirror_dest.sport,
entry->data.mirror_dest.dip,
entry->data.mirror_dest.dport);
MirrorEntryData::MirrorEntryFlags mirror_flag =
MirrorTable::DecodeMirrorFlag (intf_mirror.get_nhmode(),
intf_mirror.get_juniperheader());
if (mirror_flag == MirrorEntryData::DynamicNH_With_JuniperHdr) {
MirrorTable::AddMirrorEntry(entry->key.handle,
entry->data.mirror_dest.mirror_vrf,
entry->data.mirror_dest.sip,
entry->data.mirror_dest.sport,
entry->data.mirror_dest.dip,
entry->data.mirror_dest.dport);
} else if (mirror_flag == MirrorEntryData::DynamicNH_Without_JuniperHdr) {
MacAddress mac = MacAddress::FromString(intf_mirror.get_analyzer_vm_mac());
MirrorTable::AddMirrorEntry(entry->key.handle,
entry->data.mirror_dest.mirror_vrf,
entry->data.mirror_dest.sip,
entry->data.mirror_dest.sport,
entry->data.mirror_dest.dip,
entry->data.mirror_dest.dport, 0,
mirror_flag, mac);
} else if (mirror_flag == MirrorEntryData::StaticNH_Without_JuniperHdr) {
IpAddress dst_ip = IpAddress::from_string(intf_mirror.get_vtep_dst_ip(), ec);
if (ec.value() != 0) {
delete entry;
return "Invalid mirror destination address ";
}
MirrorTable::AddMirrorEntry(entry->key.handle,
entry->data.mirror_dest.mirror_vrf,
entry->data.mirror_dest.sip,
entry->data.mirror_dest.sport,
dst_ip, entry->data.mirror_dest.dport,
intf_mirror.get_vni(), mirror_flag,
MacAddress::ZeroMac());
} else {
return "not supported";
}

intf_mc_tree_.insert(std::pair<MirrorCfgKey, IntfMirrorCfgEntry *>(key, entry));

VmInterfaceKey *intf_key = new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE,
Expand Down
44 changes: 41 additions & 3 deletions src/vnsw/agent/filter/acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -944,9 +944,28 @@ void AclEntrySpec::AddMirrorEntry(Agent *agent) const {
}

IpAddress sip = agent->GetMirrorSourceIp(action.ma.ip);
agent->mirror_table()->AddMirrorEntry(action.ma.analyzer_name,
action.ma.vrf_name, sip, agent->mirror_port(), action.ma.ip,
action.ma.port);
MirrorEntryData::MirrorEntryFlags mirror_flag =
MirrorTable::DecodeMirrorFlag(action.ma.nh_mode,
action.ma.juniper_header);
if (mirror_flag == MirrorEntryData::DynamicNH_With_JuniperHdr) {
agent->mirror_table()->AddMirrorEntry(action.ma.analyzer_name,
action.ma.vrf_name, sip, agent->mirror_port(), action.ma.ip,
action.ma.port);
} else if (mirror_flag == MirrorEntryData::DynamicNH_Without_JuniperHdr) {
// remote_vm_analyzer mac provided from the config
agent->mirror_table()->AddMirrorEntry(action.ma.analyzer_name,
action.ma.vrf_name, sip, agent->mirror_port(), action.ma.ip,
action.ma.port, 0, mirror_flag, action.ma.mac);
} else if (mirror_flag == MirrorEntryData::StaticNH_Without_JuniperHdr) {
// Vtep dst ip & Vni will be provided from the config
agent->mirror_table()->AddMirrorEntry(action.ma.analyzer_name,
action.ma.vrf_name, sip, agent->mirror_port(),
action.ma.staticnhdata.vtep_dst_ip, action.ma.port,
action.ma.staticnhdata.vni, mirror_flag,
action.ma.staticnhdata.vtep_dst_mac);
} else {
LOG(ERROR, "Mirror nh mode not supported");
}
}
}

Expand Down Expand Up @@ -979,6 +998,25 @@ void AclEntrySpec::PopulateAction(const AclTable *acl_table,
maction.ma.analyzer_name = action_list.mirror_to.analyzer_name;
maction.ma.ip =
IpAddress::from_string(action_list.mirror_to.analyzer_ip_address, ec);
maction.ma.juniper_header = action_list.mirror_to.juniper_header;
maction.ma.nh_mode = action_list.mirror_to.nh_mode;
MirrorEntryData::MirrorEntryFlags mirror_flag =
MirrorTable::DecodeMirrorFlag (maction.ma.nh_mode,
maction.ma.juniper_header);
if (mirror_flag == MirrorEntryData::StaticNH_Without_JuniperHdr) {
maction.ma.staticnhdata.vtep_dst_ip =
IpAddress::from_string(
action_list.mirror_to.static_nh_header.vtep_dst_ip_address, ec);
maction.ma.staticnhdata.vtep_dst_mac =
MacAddress::FromString(action_list.mirror_to.static_nh_header.vtep_dst_mac_address);
maction.ma.staticnhdata.vni =
action_list.mirror_to.static_nh_header.vni;
} else if(mirror_flag == MirrorEntryData::DynamicNH_Without_JuniperHdr) {
maction.ma.vrf_name = action_list.mirror_to.routing_instance;
maction.ma.mac =
MacAddress::FromString(action_list.mirror_to.analyzer_mac_address);
}

if (ec.value() == 0) {
if (action_list.mirror_to.udp_port) {
maction.ma.port = action_list.mirror_to.udp_port;
Expand Down
10 changes: 10 additions & 0 deletions src/vnsw/agent/filter/acl_entry_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,22 @@ struct RangeSpec {
uint16_t max;
};

struct StaticMirrorNhData {
IpAddress vtep_dst_ip;
uint32_t vni;
MacAddress vtep_dst_mac;
};

struct MirrorActionSpec {
std::string analyzer_name;
std::string vrf_name;
IpAddress ip;
MacAddress mac;
uint16_t port;
std::string encap;
bool juniper_header;
std::string nh_mode;
StaticMirrorNhData staticnhdata;
bool operator == (const MirrorActionSpec &rhs) const {
return analyzer_name == rhs.analyzer_name;
}
Expand Down
10 changes: 10 additions & 0 deletions src/vnsw/agent/oper/agent.sandesh
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,11 @@ request sandesh MirrorCreateReq {
// Time period for mirroring in seconds
16: i32 time_period;
17: string mirror_vrf;
18: optional string nhmode; // dynamic or static NH
19: optional bool juniperheader;
20: optional string analyzer_vm_mac; // analyzer mac
21: optional string vtep_dst_ip;
22: optional i32 vni;
}

/**
Expand Down Expand Up @@ -1249,6 +1254,11 @@ request sandesh IntfMirrorCreateReq {
5: optional i32 udp_port;
6: optional i32 time_period;
7: optional string mirror_vrf;
8: optional string nhmode; // dynamic or static NH
9: optional bool juniperheader;
10: optional string analyzer_vm_mac; // analyzer mac
11: optional string vtep_dst_ip;
12: optional i32 vni;
}

/**
Expand Down

0 comments on commit 73aa175

Please sign in to comment.