9 #include <netinet/in.h>
83 if (bridge_rt != NULL) {
88 if (inet_rt != NULL) {
97 ref_map[vrf->
vrf_id()] = 0;
107 if (inet_rt != NULL) {
139 vrf = (
static_cast<const CompositeNH *
>(nh))->vrf();
142 case NextHop::NextHop::INTERFACE: {
144 (
static_cast<const InterfaceNH *
>(nh))->GetInterface();
179 if (comp_nh == NULL ||
232 if (!(*nh) || (*nh)->IsActive() ==
false) {
257 if (
PickEcmpMember(agent, &nh, pkt, info, ecmp_load_balance) ==
false) {
274 if (vm_port != NULL) {
276 if (alias_vrf != NULL) {
277 out->
vrf_ = alias_vrf;
348 if (local_nh && local_nh->
IsActive() ==
false) {
349 LogError(pkt, info,
"Invalid or Inactive local nexthop ");
358 if (comp_nh != NULL) {
359 out->
nh_ = comp_nh->
id();
378 const VrfNH *vrf_nh =
static_cast<const VrfNH *
>(nh);
402 const ArpNH *arp_nh =
static_cast<const ArpNH *
>(nh);
410 out->
nh_ = arp_nh->
id();
471 return NhDecode(agent, nh, pkt, info, in, out,
false,
480 return vm_port->
vn();
488 return static_cast<const VmInterface *
>(intf)->HasFloatingIp(family);
492 uint32_t sport, uint32_t dport) {
513 if (intf == NULL || in_rt == NULL || out_rt == NULL)
527 if (in_inet_rt == NULL || out_inet_rt == NULL)
600 std::string service_name;
603 pkt->dport, &service_name,
604 &nat_server, &nat_port)) {
620 std::string service_name;
622 (
pkt->ip_daddr,
pkt->dport, &service_name, &nat_server4,
634 metadata_proxy =
agent ?
636 if (metadata_proxy &&
pkt &&
637 pkt->ip_saddr.is_v6() &&
638 pkt->ip_daddr.is_v6()) {
646 if (
pkt->ip_daddr.is_v4()) {
668 nat_server = nat_server4;
674 nat_server = metadata_proxy ?
676 Ip6Address::from_string(
"::");
707 if (vm_port == NULL) {
807 GetBgpRouterServiceDestination(vm_port,
808 pkt->ip_saddr.to_v4(),
809 pkt->ip_daddr.to_v4(),
811 &sport, &dport) ==
false) {
826 boost::system::error_code ec;
862 if (
pkt->ip_daddr.is_v4()) {
867 if (
pkt->ip_daddr.is_v6()) {
874 VmInterface::FloatingIpSet::const_iterator it = fip_list.begin();
875 for ( ; it != fip_list.end(); ++it) {
877 if (it->vrf_.get() == NULL) {
881 if (
pkt->ip_daddr != it->floating_ip_) {
886 if (it->AllowDNat() ==
false) {
893 if (it == fip_list.end()) {
911 out->
vn_ = it->vn_.get();
913 if (alias_vrf == NULL) {
925 if (
pkt->ip_daddr.is_v6()) {
928 if (it->vrf_->forwarding_vrf()) {
948 if (it->port_map_enabled()) {
949 int32_t map_port = it->GetDstPortMap(
pkt->ip_proto,
pkt->dport);
981 VmInterface::FloatingIpSet::const_iterator it = fip_list.begin();
982 VmInterface::FloatingIpSet::const_iterator fip_it = fip_list.end();
990 for ( ; it != fip_list.end(); ++it) {
991 if (it->vrf_.get() == NULL) {
995 if (it->fixed_ip_ !=
IpAddress() && (
pkt->ip_saddr != it->fixed_ip_)) {
1000 if (it->AllowSNat() ==
false) {
1006 if (rt_match == NULL) {
1016 if (rt != NULL && rt_plen >= rt_match_plen) {
1021 if (out->
rt_ == NULL || rt_match_plen > out_rt_plen) {
1023 }
else if (rt_match_plen == out_rt_plen) {
1024 if (it->port_nat()) {
1026 }
else if (fip_it == fip_list.end()) {
1031 it->floating_ip_ < fip_it->floating_ip_) {
1037 if (out->
rt_ != NULL) {
1040 out->
rt_ = rt_match;
1048 if (out->
rt_ == rt) {
1054 in->
vn_ = fip_it->vn_.get();
1060 if (in->
rt_ == NULL) {
1065 if (
VrfTranslate(
pkt, in, out, fip_it->floating_ip_,
true) ==
false) {
1068 if (out->
rt_ == NULL || in->
rt_ == NULL) {
1084 if (fip_it->port_map_enabled()) {
1085 int32_t map_port = fip_it->GetSrcPortMap(
pkt->ip_proto,
pkt->sport);
1092 }
else if (fip_it->port_nat()) {
1095 if (fip_it->floating_ip_ ==
pkt->ip_daddr) {
1154 bool can_be_underlay_flow =
false;
1157 can_be_underlay_flow =
true;
1170 can_be_underlay_flow =
true;
1175 if (can_be_underlay_flow ==
false) {
1184 if (src_rt == NULL || dst_rt == NULL) {
1217 if (in->
rt_ == NULL || out->
rt_ == NULL) {
1284 if (nat_flow ==
false) {
1293 }
else if (out->
vn_) {
1376 const VrfNH *vrf_nh =
static_cast<const VrfNH *
>(nh);
1383 const NextHop *rt_nh = inet_rt ?
1391 (rt_nh)->GetInterface();
1393 static_cast<const VmInterface*
>(intf)->FloatingIpCount() == 0) {
1400 for (uint32_t i=0; i < comp_nh_count; i++) {
1407 static_cast<const VmInterface*
>(intf)->FloatingIpCount() == 0) {
1426 LogError(
pkt,
this,
"Unexpected packet on Non-VM interface");
1432 if (vm_port != NULL) {
1434 if (alias_vrf != NULL) {
1435 in->
vrf_ = alias_vrf;
1501 if (out->
rt_ != NULL) {
1513 pkt->sport,
pkt->dport))) {
1525 if (out->
intf_ == NULL && out->
rt_) {
1566 LogError(
pkt,
this,
"Invalid Label in egress flow");
1573 if (vxlan == NULL) {
1574 LogError(
pkt,
this,
"Invalid vxlan in egress flow");
1607 LogError(
pkt,
this,
"Invalid tunnel type in egress flow");
1623 LOG(ERROR,
"PktFlowInfo::EgressProcess: ARP nexthop and l3_flow "
1624 " false, DROP this frame. module " <<
pkt->module <<
" type "
1625 <<
pkt->type <<
" family " <<
pkt->family <<
" vrf " <<
pkt->vrf
1626 <<
" tunnel_type " <<
pkt->tunnel.type.GetType()<<
" ifindex "
1627 <<
pkt->agent_hdr.ifindex <<
" sip " <<
pkt->ip_saddr.to_string()
1628 <<
" dip " <<
pkt->ip_daddr.to_string() <<
" proto " <<
pkt->ip_proto
1629 <<
" sport " <<
pkt->sport <<
" dport " <<
pkt->dport<<
" l3_label "
1635 if (comp_nh != NULL) {
1645 ecmp_load_balance) ==
false) {
1655 if (alias_vrf != NULL) {
1656 out->
vrf_ = alias_vrf;
1665 if (out->
vrf_ == NULL) {
1701 ecmp_load_balance()),
ingress);
1738 }
else if (in->
rt_ == NULL && out->
rt_) {
1749 if (vxlan && vxlan->
nexthop()) {
1750 const VrfNH *vrf_nh =
1770 IsBFDHealthCheckPacket(pkt, interface)) ||
1772 IsSegmentHealthCheckPacket(pkt, interface)));
1785 if (in->
intf_ == NULL) {
1795 (
pkt->ip_saddr.is_v6() && !
pkt->ip_saddr.to_v6().is_link_local()) &&
1796 (
pkt->ip_daddr.is_v6() && !
pkt->ip_daddr.to_v6().is_link_local())) {
1798 LogError(
pkt,
this,
"IP protocol inactive on interface");
1805 LogError(
pkt,
this,
"IP service not enabled for interface");
1821 if (vm_intf && vm_intf->
bridging() ==
false) {
1822 LogError(
pkt,
this,
"Bridge service not enabled for interface");
1868 (
pkt->is_fat_flow_dst_prefix))) {
1870 LogError(
pkt,
this,
"Flow : Fat-flow and NAT cannot co-exist");
1878 LogError(
pkt,
this,
"Flow : No route for Src-IP");
1885 LogError(
pkt,
this,
"Flow : No route for Dst-IP");
1898 LogError(
pkt,
this,
"Flow : Overlay route not found");
1936 bool enqueue_traffic_seen =
false;
1944 }
else if (in->
vrf_) {
1951 enqueue_traffic_seen =
true;
1953 }
else if (vm_intf) {
1963 enqueue_traffic_seen =
true;
1973 enqueue_traffic_seen =
true;
1979 if (enqueue_traffic_seen) {
1981 EnqueueTrafficSeen(sip, plen, in->
intf_->
id(),
1994 bool limit_exceeded =
false;
1995 uint32_t vmi_max_flows;
2000 uint32_t maxv = std::max(vm_intf->
max_flows(),
2002 uint32_t minv = std::min(vm_intf->
max_flows(),
2010 if ((vm_intf->
flow_count() + 2) > vmi_max_flows) {
2011 limit_exceeded =
true;
2021 uint32_t maxv = std::max(vm_intf->
max_flows(),
2023 uint32_t minv = std::min(vm_intf->
max_flows(),
2031 if ((vm_intf->
flow_count() + 2) > vmi_max_flows) {
2032 limit_exceeded =
true;
2040 limit_exceeded =
true;
2045 limit_exceeded =
true;
2048 if (limit_exceeded) {
2061 limit_exceeded =
true;
2069 limit_exceeded =
true;
2073 if (limit_exceeded) {
2118 if (flow.get() && flow->deleted() ==
false) {
2120 pkt->agent_hdr.cmd_param_3,
2121 pkt->agent_hdr.cmd_param_4, flow->uuid());
2127 bool update =
false;
2158 if (
pkt->is_fat_flow_src_prefix) {
2159 sip =
pkt->ip_ff_src_prefix;
2161 if (
pkt->is_fat_flow_dst_prefix) {
2162 dip =
pkt->ip_ff_dst_prefix;
2173 assert(rflow == NULL);
2179 r_sport =
pkt->sport;
2180 r_dport =
pkt->dport;
2185 r_sport =
pkt->dport;
2186 r_dport =
pkt->sport;
2195 if (
pkt->same_port_number && (in->
nh_ == out->
nh_)) {
2199 r_sport =
pkt->sport;
2200 r_dport =
pkt->dport;
2202 FlowKey rkey(out->
nh_, dip, sip,
pkt->ip_proto, r_sport, r_dport);
2206 bool swap_flows =
false;
2212 assert(rflow != NULL);
2217 flow->InitFwdFlow(
this,
pkt, in, out, rflow.get(),
agent);
2218 if (rflow != NULL) {
2219 rflow->InitRevFlow(
this,
pkt, out, in, flow.get(),
agent);
2222 flow->GetPolicyInfo();
2223 if (rflow != NULL) {
2224 rflow->GetPolicyInfo();
2228 if (rflow != NULL) {
2229 rflow->ResyncFlow();
2243 FlowEntry *tmp = swap_flows ? rflow.get() : flow.get();
2259 uint32_t intf_id, r_intf_id;
2260 uint32_t fip, r_fip;
2283 nat_key = &(flow->
key());
2286 r_fip =
snat_fip.to_v4().to_ulong();
2295 intf_id = r_intf_id = in->
intf_->
id();
2297 fip = r_fip =
pkt->ip_daddr.to_v4().to_ulong();
2298 intf_id = r_intf_id = out->
intf_->
id();
2303 if (rflow != NULL) {
2310 family = pkt_info->family;
boost::asio::ip::address_v6 Ip6Address
boost::asio::ip::address IpAddress
boost::asio::ip::address_v4 Ip4Address
#define FLOWS_LIMIT_UNLIMITED
#define METADATA_NAT_PORT
std::set< std::string > VnListType
bool PacketMatch(const PacketHeader &packet_header, MatchAclParams &m_acl, FlowPolicyInfo *info) const
AgentDBEntry * FindActiveEntry(const DBEntry *key)
uint32_t linklocal_vm_flows() const
uint32_t linklocal_system_flows() const
const VnListType & dest_vn_list() const
const EcmpLoadBalance & ecmp_load_balance() const
const SecurityGroupList & sg_list() const
uint32_t tunnel_bmap() const
const Peer * peer() const
virtual const NextHop * ComputeNextHop(Agent *agent) const
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
void set_prefix_length(uint8_t new_plen)
Sets the length of a stored prefix address.
Base class for all Route entries in agent.
const AgentPath * GetActivePath() const
const NextHop * GetActiveNextHop() const
bool WaitForTraffic() const
virtual uint8_t prefix_length() const
Returns the length of a stored prefix address.
virtual Agent::RouteTableType GetTableType() const =0
void incr_flow_drop_due_to_max_limit()
InterfaceTable * interface_table() const
ServicesModule * services() const
static const std::set< std::string > & NullStringList()
FlowProto * GetFlowProto() const
uint16_t metadata_server_port() const
AgentParam * params() const
VrfTable * vrf_table() const
uint32_t global_max_vmi_flows() const
VxLanTable * vxlan_table() const
Ip4Address compute_node_ip() const
VrfEntry * fabric_vrf() const
uint32_t max_vm_flows() const
const Peer * link_local_peer() const
const Interface * vhost_interface() const
AgentStats * stats() const
const std::string & fabric_vrf_name() const
Ip4Address router_id() const
MplsTable * mpls_table() const
const Interface * GetInterface() const
const VrfEntry * GetVrf() const
static const uint32_t DefaultBgpPort
uint32_t hash(uint32_t seed, bool ingress) const
const VrfEntry * vrf() const
static const uint32_t kInvalidComponentNHIdx
size_t ComponentNHCount() const
const NextHop * GetNH(uint32_t idx) const
COMPOSITETYPE composite_nh_type() const
bool GetIndex(ComponentNH &nh, uint32_t &idx) const
uint32_t PickMember(uint32_t seed, uint32_t affinity_index, bool ingress) const
static const NextHop * GetLocalNextHop(const AgentRoute *rt)
uint8_t prefix_length() const
!
const FlowKey & key() const
static const uint32_t kInvalidFlowHandle
bool is_flags_set(const FlowEntryFlags &flags) const
static AgentRoute * GetL2Route(const VrfEntry *entry, const MacAddress &mac)
VmFlowRef * in_vm_flow_ref()
static FlowEntry * Allocate(const FlowKey &key, FlowTable *flow_table)
void UpdateFipStatsInfo(uint32_t fip, uint32_t id, Agent *agent)
static AgentRoute * GetUcRoute(const VrfEntry *entry, const IpAddress &addr)
@ SHORT_FAT_FLOW_NAT_CONFLICT
@ SHORT_UNAVIALABLE_INTERFACE
@ SHORT_LINKLOCAL_SRC_NAT
static AgentRoute * GetEvpnRoute(const VrfEntry *entry, const MacAddress &mac, const IpAddress &addr, uint32_t ethernet_tag)
void FlowStatsUpdateEvent(FlowEntry *flow, uint32_t bytes, uint32_t packets, uint32_t oflow_bytes, const boost::uuids::uuid &u)
uint32_t linklocal_flow_count() const
bool UpdateFlow(FlowEntry *flow)
PortTableManager * port_table_manager()
bool AddFlow(FlowEntry *flow)
uint16_t table_index() const
bool FindLinkLocalService(const std::string &service_name, IpAddress *service_ip, uint16_t *service_port, std::string *fabric_hostname, Ip4Address *fabric_ip, uint16_t *fabric_port) const
Get link local service configuration info, for a given service name.
uint8_t prefix_length() const
!
const Interface * GetInterface() const
const Interface * FindInterface(size_t index) const
const NextHop * flow_key_nh() const
bool ip_active(Address::Family family) const
static const uint32_t kInvalidIndex
const uint32_t id() const
FlowEntryPtr FindByIndex(uint32_t idx)
KSyncFlowIndexManager * ksync_flow_index_manager() const
const NextHop * nexthop() const
MplsLabel * FindMplsLabel(uint32_t label)
GlobalVrouter * global_vrouter() const
BgpAsAService * bgp_as_a_service() const
PathPreferenceModule * route_preference_module() const
void Add(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
bool ValidateConfig(const PktInfo *pkt, PktControlInfo *in)
bool Process(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void CheckLinkLocal(const PktInfo *pkt)
void LinkLocalPortBind(const PktInfo *pkt, const PktControlInfo *in, FlowEntry *flow)
void ChangeVrf(const PktInfo *pkt, PktControlInfo *info, const VrfEntry *vrf)
void LinkLocalServiceFromHost(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
FlowRouteRefMap flow_dest_plen_map
boost::shared_ptr< PktInfo > pkt
bool EgressRouteAllowNatLookup(const AgentRoute *in_rt, const AgentRoute *out_rt, uint32_t sport, uint32_t dport, const Interface *intf)
void ChangeEncap(const VmInterface *intf, const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out, bool nat_flow)
bool linklocal_bind_local_port
IpAddress FamilyToAddress(Address::Family family)
void ChangeFloatingIpEncap(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void GenerateTrafficSeen(const PktInfo *pkt, const PktControlInfo *in)
uint8_t RouteToPrefixLen(const AgentRoute *route)
const NextHop * TunnelToNexthop(const PktInfo *pkt)
bool IngressRouteAllowNatLookup(const AgentRoute *in_rt, const AgentRoute *out_rt, uint32_t sport, uint32_t dport, const Interface *intf)
bool bgp_router_service_flow
void IngressProcess(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void UpdateFipStatsInfo(FlowEntry *flow, FlowEntry *rflow, const PktInfo *p, const PktControlInfo *in, const PktControlInfo *o)
uint32_t out_component_nh_idx
static const Ip6Address kDefaultIpv6
void FloatingIpDNat(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void SetPktInfo(boost::shared_ptr< PktInfo > info)
void LinkLocalServiceTranslate(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
bool overlay_route_not_found
bool flood_unknown_unicast
void NatVxlanVrfTranslate(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
bool VrfTranslate(const PktInfo *pkt, PktControlInfo *ctrl, PktControlInfo *rev_flow, const IpAddress &src_ip, bool nat_flow)
uint16_t short_flow_reason
void EgressProcess(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
const VnListType * dst_vn
void BgpRouterServiceTranslate(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
static const Ip4Address kDefaultIpv4
bool IsBgpRouterServiceRoute(const AgentRoute *in_rt, const AgentRoute *out_rt, const Interface *intf, uint32_t sport, uint32_t dport)
void UpdateRoute(const AgentRoute **rt, const VrfEntry *vrf, const IpAddress &addr, const MacAddress &mac, FlowRouteRefMap &ref_map)
bool UnknownUnicastFlow(const PktInfo *p, const PktControlInfo *in_info, const PktControlInfo *out_info)
void FloatingIpSNat(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
bool RouteAllowNatLookupCommon(const AgentRoute *rt, uint32_t sport, uint32_t dport, const Interface *intf)
FlowRouteRefMap flow_source_plen_map
const VnListType * src_vn
void UpdateEvictedFlowStats(const PktInfo *pkt)
void LinkLocalServiceFromVm(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void ApplyFlowLimits(const PktControlInfo *in, const PktControlInfo *out)
void BgpRouterServiceFromVm(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
static bool ComputeDirection(const Interface *intf)
void ChangeEncapToOverlay(const VmInterface *intf, const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
FlowProto * get_flow_proto() const
FlowMgmtManager * flow_mgmt_manager(uint16_t index) const
PktHandler * pkt_handler() const
uint16_t Allocate(const FlowKey &key)
const Interface * get_interface() const
MetadataProxy * metadataproxy()
const TunnelType & GetTunnelType() const
const Ip4Address * GetDip() const
const Interface * GetInterface() const
uint16_t GetVlanTag() const
const VrfEntry * GetVrf() const
uint32_t linklocal_flow_count() const
uint32_t flow_count() const
bool AllocateFd(Agent *agent, uint8_t l3_proto)
static const int kInvalidFd
bool layer3_forwarding() const
VmInterface::VmiType vmi_type() const
uint32_t max_flows() const
uint32_t ethernet_tag() const
const FloatingIpList & floating_ip_list() const
uint32_t flow_count() const
std::set< FloatingIp, FloatingIp > FloatingIpSet
bool IsFloatingIp(const IpAddress &ip) const
Ip6Address mdata_ip6_addr() const
bool flood_unknown_unicast() const
VmInterface::DeviceType device_type() const
const VnEntry * vn() const
const Ip4Address & primary_ip_addr() const
MetaDataIp * GetMetaDataIp(const IpAddress &ip) const
Ip4Address mdata_ip_addr() const
const Ip6Address & primary_ip6_addr() const
VrfEntry * GetAliasIpVrf(const IpAddress &ip) const
const AclDBEntry * vrf_assign_acl() const
const AclDBEntry * GetAcl() const
bool vxlan_routing_vn() const
const string & GetName() const
InetUnicastRouteEntry * GetUcRoute(const IpAddress &addr) const
static const uint32_t kInvalidIndex
const uint32_t vrf_id() const
VrfEntry * forwarding_vrf() const
bool flood_unknown_unicast() const
const VrfEntry * GetVrf() const
VrfEntry * FindVrfFromName(const string &name)
VrfEntry * FindVrfFromId(size_t index)
const NextHop * nexthop() const
VxLanId * FindNoLock(uint32_t vxlan_id)
boost::intrusive_ptr< FlowEntry > FlowEntryPtr
#define FLOW_TRACE(obj,...)
#define LOG(_Level, _Msg)
static uint32_t NhToVrf(const NextHop *nh)
static bool NhDecode(const Agent *agent, const NextHop *nh, const PktInfo *pkt, PktFlowInfo *info, PktControlInfo *in, PktControlInfo *out, bool force_vmport, const EcmpLoadBalance &ecmp_load_balance)
static bool IntfHasFloatingIp(PktFlowInfo *pkt_info, const Interface *intf, Address::Family family)
static void LogError(const PktInfo *pkt, const PktFlowInfo *flow_info, const char *str)
static bool IsLinkLocalRoute(Agent *agent, const AgentRoute *rt, uint32_t sport, uint32_t dport)
static bool PickEcmpMember(const Agent *agent, const NextHop **nh, const PktInfo *pkt, PktFlowInfo *info, const EcmpLoadBalance &ecmp_load_balance)
static bool IsVgwOrVmInterface(const Interface *intf)
static const VnListType * RouteToVn(const AgentRoute *rt)
static bool RouteToOutInfo(const Agent *agent, const AgentRoute *rt, const PktInfo *pkt, PktFlowInfo *info, PktControlInfo *in, PktControlInfo *out)
bool IsValidationDisabled(Agent *agent, const PktInfo *pkt, const Interface *interface)
static const VnEntry * InterfaceToVn(const Interface *intf)
map< int, int > FlowRouteRefMap
VrfTranslateActionSpec vrf_translate_action_
std::size_t hash(const Agent *agent, const EcmpLoadBalance &ecmp_has_fields_to_use) const
const std::string & vrf_name() const