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);
387 const ArpNH *arp_nh =
static_cast<const ArpNH *
>(nh);
395 out->
nh_ = arp_nh->
id();
456 return NhDecode(agent, nh, pkt, info, in, out,
false,
465 return vm_port->
vn();
473 return static_cast<const VmInterface *
>(intf)->HasFloatingIp(family);
477 uint32_t sport, uint32_t dport) {
498 if (intf == NULL || in_rt == NULL || out_rt == NULL)
512 if (in_inet_rt == NULL || out_inet_rt == NULL)
541 if (dynamic_cast<const BridgeRouteEntry *>(rt) != NULL)
585 std::string service_name;
588 pkt->
dport, &service_name,
589 &nat_server, &nat_port)) {
605 std::string service_name;
619 metadata_proxy =
agent ?
621 if (metadata_proxy && pkt &&
653 nat_server = nat_server4;
659 nat_server = metadata_proxy ?
661 Ip6Address::from_string(
"::");
692 if (vm_port == NULL) {
792 GetBgpRouterServiceDestination(vm_port,
796 &sport, &dport) ==
false) {
811 boost::system::error_code ec;
859 VmInterface::FloatingIpSet::const_iterator it = fip_list.begin();
860 for ( ; it != fip_list.end(); ++it) {
862 if (it->vrf_.get() == NULL) {
866 if (pkt->
ip_daddr != it->floating_ip_) {
871 if (it->AllowDNat() ==
false) {
878 if (it == fip_list.end()) {
896 out->
vn_ = it->vn_.get();
898 if (alias_vrf == NULL) {
913 if (it->vrf_->forwarding_vrf()) {
933 if (it->port_map_enabled()) {
934 int32_t map_port = it->GetDstPortMap(pkt->
ip_proto, pkt->
dport);
966 VmInterface::FloatingIpSet::const_iterator it = fip_list.begin();
967 VmInterface::FloatingIpSet::const_iterator fip_it = fip_list.end();
975 for ( ; it != fip_list.end(); ++it) {
976 if (it->vrf_.get() == NULL) {
985 if (it->AllowSNat() ==
false) {
991 if (rt_match == NULL) {
1001 if (rt != NULL && rt_plen >= rt_match_plen) {
1006 if (out->
rt_ == NULL || rt_match_plen > out_rt_plen) {
1008 }
else if (rt_match_plen == out_rt_plen) {
1009 if (it->port_nat()) {
1011 }
else if (fip_it == fip_list.end()) {
1016 it->floating_ip_ < fip_it->floating_ip_) {
1022 if (out->
rt_ != NULL) {
1025 out->
rt_ = rt_match;
1033 if (out->
rt_ == rt) {
1039 in->
vn_ = fip_it->vn_.get();
1045 if (in->
rt_ == NULL) {
1050 if (
VrfTranslate(pkt, in, out, fip_it->floating_ip_,
true) ==
false) {
1053 if (out->
rt_ == NULL || in->
rt_ == NULL) {
1069 if (fip_it->port_map_enabled()) {
1070 int32_t map_port = fip_it->GetSrcPortMap(pkt->
ip_proto, pkt->
sport);
1077 }
else if (fip_it->port_nat()) {
1080 if (fip_it->floating_ip_ == pkt->
ip_daddr) {
1139 bool can_be_underlay_flow =
false;
1142 can_be_underlay_flow =
true;
1155 can_be_underlay_flow =
true;
1160 if (can_be_underlay_flow ==
false) {
1169 if (src_rt == NULL || dst_rt == NULL) {
1176 uint32_t dst_tunnel_bmap = dst_rt->GetActivePath()->tunnel_bmap();
1202 if (in->
rt_ == NULL || out->
rt_ == NULL) {
1269 if (nat_flow ==
false) {
1278 }
else if (out->
vn_) {
1318 if (!acl->
PacketMatch(hdr, match_acl_param, NULL)) {
1361 const VrfNH *vrf_nh =
static_cast<const VrfNH *
>(nh);
1368 const NextHop *rt_nh = inet_rt ?
1376 (rt_nh)->GetInterface();
1378 static_cast<const VmInterface*
>(intf)->FloatingIpCount() == 0) {
1385 for (uint32_t i=0; i < comp_nh_count; i++) {
1392 static_cast<const VmInterface*
>(intf)->FloatingIpCount() == 0) {
1411 LogError(pkt,
this,
"Unexpected packet on Non-VM interface");
1417 if (vm_port != NULL) {
1419 if (alias_vrf != NULL) {
1420 in->
vrf_ = alias_vrf;
1486 if (out->
rt_ != NULL) {
1510 if (out->
intf_ == NULL && out->
rt_) {
1551 LogError(pkt,
this,
"Invalid Label in egress flow");
1558 if (vxlan == NULL) {
1559 LogError(pkt,
this,
"Invalid vxlan in egress flow");
1592 LogError(pkt,
this,
"Invalid tunnel type in egress flow");
1608 LOG(ERROR,
"PktFlowInfo::EgressProcess: ARP nexthop and l3_flow "
1609 " false, DROP this frame. module " << pkt->
module <<
" type "
1610 << pkt->
type <<
" family " << pkt->
family <<
" vrf " <<pkt->
vrf
1614 <<
" sport " << pkt->
sport <<
" dport " <<pkt->
dport<<
" l3_label "
1620 if (comp_nh != NULL) {
1630 ecmp_load_balance) ==
false) {
1640 if (alias_vrf != NULL) {
1641 out->
vrf_ = alias_vrf;
1650 if (out->
vrf_ == NULL) {
1686 ecmp_load_balance()),
ingress);
1723 }
else if (in->
rt_ == NULL && out->
rt_) {
1734 if (vxlan && vxlan->
nexthop()) {
1735 const VrfNH *vrf_nh =
1755 IsBFDHealthCheckPacket(pkt, interface)) ||
1757 IsSegmentHealthCheckPacket(pkt, interface)));
1770 if (in->
intf_ == NULL) {
1771 LogError(pkt,
this,
"Invalid interface");
1783 LogError(pkt,
this,
"IP protocol inactive on interface");
1790 LogError(pkt,
this,
"IP service not enabled for interface");
1800 LogError(pkt,
this,
"L2 inactive on interface");
1806 if (vm_intf && vm_intf->
bridging() ==
false) {
1807 LogError(pkt,
this,
"Bridge service not enabled for interface");
1816 LogError(pkt,
this,
"Invalid or Inactive VRF");
1855 LogError(pkt,
this,
"Flow : Fat-flow and NAT cannot co-exist");
1863 LogError(pkt,
this,
"Flow : No route for Src-IP");
1870 LogError(pkt,
this,
"Flow : No route for Dst-IP");
1883 LogError(pkt,
this,
"Flow : Overlay route not found");
1921 bool enqueue_traffic_seen =
false;
1929 }
else if (in->
vrf_) {
1936 enqueue_traffic_seen =
true;
1938 }
else if (vm_intf) {
1948 enqueue_traffic_seen =
true;
1958 enqueue_traffic_seen =
true;
1964 if (enqueue_traffic_seen) {
1966 EnqueueTrafficSeen(sip, plen, in->
intf_->
id(),
1979 bool limit_exceeded =
false;
1980 bool interface_max_flow =
false;
1986 interface_max_flow =
true;
1988 limit_exceeded =
true;
1998 interface_max_flow =
true;
2000 limit_exceeded =
true;
2007 limit_exceeded =
true;
2012 limit_exceeded =
true;
2015 if (limit_exceeded) {
2028 limit_exceeded =
true;
2036 limit_exceeded =
true;
2040 if (limit_exceeded) {
2085 if (flow.get() && flow->deleted() ==
false) {
2094 bool update =
false;
2140 assert(rflow == NULL);
2146 r_sport = pkt->
sport;
2147 r_dport = pkt->
dport;
2152 r_sport = pkt->
dport;
2153 r_dport = pkt->
sport;
2166 r_sport = pkt->
sport;
2167 r_dport = pkt->
dport;
2173 bool swap_flows =
false;
2179 assert(rflow != NULL);
2184 flow->InitFwdFlow(
this, pkt, in, out, rflow.get(),
agent);
2185 if (rflow != NULL) {
2186 rflow->InitRevFlow(
this, pkt, out, in, flow.get(),
agent);
2189 flow->GetPolicyInfo();
2190 if (rflow != NULL) {
2191 rflow->GetPolicyInfo();
2195 if (rflow != NULL) {
2196 rflow->ResyncFlow();
2210 FlowEntry *tmp = swap_flows ? rflow.get() : flow.get();
2226 uint32_t intf_id, r_intf_id;
2227 uint32_t fip, r_fip;
2232 if (fip_snat && fip_dnat && rflow != NULL) {
2243 fip = snat_fip.to_v4().to_ulong();
2250 nat_key = &(flow->
key());
2253 r_fip = snat_fip.to_v4().to_ulong();
2260 }
else if (fip_snat) {
2261 fip = r_fip = nat_ip_saddr.to_v4().to_ulong();
2262 intf_id = r_intf_id = in->
intf_->
id();
2263 }
else if (fip_dnat) {
2264 fip = r_fip = pkt->
ip_daddr.to_v4().to_ulong();
2265 intf_id = r_intf_id = out->
intf_->
id();
2268 if (fip_snat || fip_dnat) {
2270 if (rflow != NULL) {
2277 family = pkt_info->family;
uint32_t PickMember(uint32_t seed, uint32_t affinity_index, bool ingress) const
VrfEntry * GetAliasIpVrf(const IpAddress &ip) const
uint8_t prefix_length() const
!
bool AllocateFd(Agent *agent, uint8_t l3_proto)
void SetPktInfo(boost::shared_ptr< PktInfo > info)
bool linklocal_bind_local_port
static const Ip6Address kDefaultIpv6
static bool IsVgwOrVmInterface(const Interface *intf)
const Interface * GetInterface() const
uint32_t flow_count() const
bool bgp_router_service_flow
const VnListType & dest_vn_list() const
bool is_fat_flow_src_prefix
static const VnEntry * InterfaceToVn(const Interface *intf)
ServicesModule * services() const
const VrfEntry * GetVrf() const
bool flood_unknown_unicast
virtual uint8_t prefix_length() const
Returns the length of a stored prefix address.
bool ip_active(Address::Family family) const
bool UnknownUnicastFlow(const PktInfo *p, const PktControlInfo *in_info, const PktControlInfo *out_info)
bool IsFloatingIp(const IpAddress &ip) const
static const NextHop * GetLocalNextHop(const AgentRoute *rt)
static const uint32_t kInvalidComponentNHIdx
MetadataProxy * metadataproxy()
VrfEntry * fabric_vrf() const
Ip4Address compute_node_ip() const
const AclDBEntry * GetAcl() const
const VrfEntry * GetVrf() const
VrfEntry * FindVrfFromName(const string &name)
const uint32_t id() const
static const VnListType * RouteToVn(const AgentRoute *rt)
Ip4Address mdata_ip_addr() const
bool WaitForTraffic() const
bool IngressRouteAllowNatLookup(const AgentRoute *in_rt, const AgentRoute *out_rt, uint32_t sport, uint32_t dport, const Interface *intf)
PktHandler::PktModuleName module
const Interface * vhost_interface() const
static bool RouteToOutInfo(const Agent *agent, const AgentRoute *rt, const PktInfo *pkt, PktFlowInfo *info, PktControlInfo *in, PktControlInfo *out)
VmInterface::DeviceType device_type() const
const VnListType * src_vn
const NextHop * nexthop() const
boost::asio::ip::address IpAddress
void incr_flow_drop_due_to_max_limit()
AgentStats * stats() const
IpAddress ip_ff_src_prefix
uint32_t out_component_nh_idx
uint32_t linklocal_flow_count() const
const NextHop * TunnelToNexthop(const PktInfo *pkt)
void BgpRouterServiceFromVm(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
bool EgressRouteAllowNatLookup(const AgentRoute *in_rt, const AgentRoute *out_rt, uint32_t sport, uint32_t dport, const Interface *intf)
AgentDBEntry * FindActiveEntry(const DBEntry *key)
InterfaceTable * interface_table() const
const Ip4Address * GetDip() const
FlowRouteRefMap flow_source_plen_map
uint32_t max_vm_flows() const
uint16_t table_index() const
void set_prefix_length(uint8_t new_plen)
Sets the length of a stored prefix address.
FlowEntryPtr FindByIndex(uint32_t idx)
const string & GetName() const
static AgentRoute * GetEvpnRoute(const VrfEntry *entry, const MacAddress &mac, const IpAddress &addr, uint32_t ethernet_tag)
static AgentRoute * GetL2Route(const VrfEntry *entry, const MacAddress &mac)
uint16_t GetVlanTag() const
PortTableManager * port_table_manager()
const std::string & vrf_name() const
MplsTable * mpls_table() const
bool RouteAllowNatLookupCommon(const AgentRoute *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)
void UpdateEvictedFlowStats(const PktInfo *pkt)
static FlowEntry * Allocate(const FlowKey &key, FlowTable *flow_table)
Base class for all Route entries in agent.
const VrfEntry * vrf() const
VmFlowRef * in_vm_flow_ref()
static const int kInvalidFd
const NextHop * flow_key_nh() const
uint16_t Allocate(const FlowKey &key)
#define METADATA_NAT_PORT
void LinkLocalPortBind(const PktInfo *pkt, const PktControlInfo *in, FlowEntry *flow)
void ChangeFloatingIpEncap(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
boost::shared_ptr< PktInfo > pkt
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.
void UpdateRoute(const AgentRoute **rt, const VrfEntry *vrf, const IpAddress &addr, const MacAddress &mac, FlowRouteRefMap &ref_map)
const VnListType * dst_vn
bool ValidateConfig(const PktInfo *pkt, PktControlInfo *in)
void IngressProcess(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
const Interface * GetInterface() const
const FlowKey & key() const
const std::string & fabric_vrf_name() const
IpAddress FamilyToAddress(Address::Family family)
const AgentPath * GetActivePath() const
virtual Agent::RouteTableType GetTableType() const =0
BgpAsAService * bgp_as_a_service() const
static void LogError(const PktInfo *pkt, const PktFlowInfo *flow_info, const char *str)
const Peer * link_local_peer() const
GlobalVrouter * global_vrouter() const
VrfEntry * FindVrfFromId(size_t index)
void FloatingIpSNat(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
bool is_flags_set(const FlowEntryFlags &flags) const
void GenerateTrafficSeen(const PktInfo *pkt, const PktControlInfo *in)
bool flood_unknown_unicast() const
VrfTranslateActionSpec vrf_translate_action_
PathPreferenceModule * route_preference_module() const
const TunnelType & GetTunnelType() const
const NextHop * GetActiveNextHop() const
IpAddress ip_ff_dst_prefix
boost::asio::ip::address_v6 Ip6Address
Ip4Address router_id() const
bool VrfTranslate(const PktInfo *pkt, PktControlInfo *ctrl, PktControlInfo *rev_flow, const IpAddress &src_ip, bool nat_flow)
map< int, int > FlowRouteRefMap
uint32_t linklocal_flow_count() const
bool IsValidationDisabled(Agent *agent, const PktInfo *pkt, const Interface *interface)
bool vxlan_routing_vn() const
bool layer3_forwarding() const
bool IsBgpRouterServiceRoute(const AgentRoute *in_rt, const AgentRoute *out_rt, const Interface *intf, uint32_t sport, uint32_t dport)
uint32_t linklocal_system_flows() const
bool Process(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
const Peer * peer() const
static bool ComputeDirection(const Interface *intf)
PktHandler * pkt_handler() const
void Add(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
#define FLOW_TRACE(obj,...)
const VnEntry * vn() const
static const uint32_t DefaultBgpPort
static AgentRoute * GetUcRoute(const VrfEntry *entry, const IpAddress &addr)
Ip6Address mdata_ip6_addr() const
COMPOSITETYPE composite_nh_type() const
AgentParam * params() const
uint32_t flow_count() const
static const std::set< std::string > & NullStringList()
void FlowStatsUpdateEvent(FlowEntry *flow, uint32_t bytes, uint32_t packets, uint32_t oflow_bytes, const boost::uuids::uuid &u)
const uint32_t vrf_id() const
std::set< std::string > VnListType
const AclDBEntry * vrf_assign_acl() const
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
boost::asio::ip::address_v4 Ip4Address
FlowProto * get_flow_proto() const
const NextHop * nexthop() const
VrfTable * vrf_table() const
const Ip4Address & primary_ip_addr() const
const FloatingIpList & floating_ip_list() const
static const Ip4Address kDefaultIpv4
uint32_t hash(uint32_t seed, bool ingress) const
bool PacketMatch(const PacketHeader &packet_header, MatchAclParams &m_acl, FlowPolicyInfo *info) const
uint8_t RouteToPrefixLen(const AgentRoute *route)
uint8_t prefix_length() const
!
FlowProto * GetFlowProto() const
VxLanTable * vxlan_table() const
VmInterface::VmiType vmi_type() const
const VrfEntry * GetVrf() const
uint16_t short_flow_reason
static const uint32_t kInvalidIndex
const Ip6Address & primary_ip6_addr() const
static bool PickEcmpMember(const Agent *agent, const NextHop **nh, const PktInfo *pkt, PktFlowInfo *info, const EcmpLoadBalance &ecmp_load_balance)
uint32_t max_flows() const
size_t ComponentNHCount() const
static const uint32_t kInvalidFlowHandle
std::set< FloatingIp, FloatingIp > FloatingIpSet
const Interface * FindInterface(size_t index) const
VrfEntry * forwarding_vrf() const
static const uint32_t kInvalidIndex
#define LOG(_Level, _Msg)
uint32_t ethernet_tag() const
void BgpRouterServiceTranslate(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void LinkLocalServiceFromVm(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
MplsLabel * FindMplsLabel(uint32_t label)
void ChangeVrf(const PktInfo *pkt, PktControlInfo *info, const VrfEntry *vrf)
bool GetIndex(ComponentNH &nh, uint32_t &idx) const
const Interface * get_interface() const
bool overlay_route_not_found
virtual const NextHop * ComputeNextHop(Agent *agent) const
uint32_t linklocal_vm_flows() const
void CheckLinkLocal(const PktInfo *pkt)
static uint32_t NhToVrf(const NextHop *nh)
bool is_fat_flow_dst_prefix
static bool IsLinkLocalRoute(Agent *agent, const AgentRoute *rt, uint32_t sport, uint32_t dport)
const NextHop * GetNH(uint32_t idx) const
void UpdateFipStatsInfo(uint32_t fip, uint32_t id, Agent *agent)
void NatVxlanVrfTranslate(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
KSyncFlowIndexManager * ksync_flow_index_manager() const
uint16_t metadata_server_port() const
uint32_t tunnel_bmap() const
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)
FlowMgmtManager * flow_mgmt_manager(uint16_t index) const
VmInterface::FatFlowIgnoreAddressType ignore_address
InetUnicastRouteEntry * GetUcRoute(const IpAddress &addr) const
FlowRouteRefMap flow_dest_plen_map
void ApplyFlowLimits(const PktControlInfo *in, const PktControlInfo *out)
const Interface * GetInterface() const
bool UpdateFlow(FlowEntry *flow)
void ChangeEncapToOverlay(const VmInterface *intf, const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
std::size_t hash(const Agent *agent, const EcmpLoadBalance &ecmp_has_fields_to_use) const
void EgressProcess(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void LinkLocalServiceTranslate(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
void LinkLocalServiceFromHost(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
VxLanId * FindNoLock(uint32_t vxlan_id)
const SecurityGroupList & sg_list() const
MetaDataIp * GetMetaDataIp(const IpAddress &ip) const
const EcmpLoadBalance & ecmp_load_balance() const
bool AddFlow(FlowEntry *flow)
void UpdateFipStatsInfo(FlowEntry *flow, FlowEntry *rflow, const PktInfo *p, const PktControlInfo *in, const PktControlInfo *o)
bool flood_unknown_unicast() const
boost::intrusive_ptr< FlowEntry > FlowEntryPtr
void FloatingIpDNat(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out)
static bool IntfHasFloatingIp(PktFlowInfo *pkt_info, const Interface *intf, Address::Family family)