/
pkt_flow_info.h
206 lines (186 loc) · 8.54 KB
/
pkt_flow_info.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#ifndef __agent_pkt_flow_info_h_
#define __agent_pkt_flow_info_h_
class VrfEntry;
class Interface;
class VnEntry;
class VmEntry;
class FlowTable;
class FlowEntry;
class AgentRoute;
struct PktInfo;
struct MatchPolicy;
typedef map<int, int> FlowRouteRefMap;
struct PktControlInfo {
PktControlInfo() :
vrf_(NULL), intf_(NULL), rt_(NULL), vn_(NULL), vm_(NULL),
vlan_nh_(false), vlan_tag_(0), nh_(0) { }
virtual ~PktControlInfo() { }
const VrfEntry *vrf_;
const Interface *intf_;
const AgentRoute *rt_;
const VnEntry *vn_;
const VmEntry *vm_;
bool vlan_nh_;
uint16_t vlan_tag_;
// The NH-ID field used as key in the flow
uint32_t nh_;
};
class PktFlowInfo {
public:
static const int kLinkLocalInvalidFd = -1;
static const Ip4Address kDefaultIpv4;
static const Ip6Address kDefaultIpv6;
static const int kBgpRouterServiceInvalidFd = -1;
PktFlowInfo(Agent *a, boost::shared_ptr<PktInfo> info, FlowTable *ftable) :
l3_flow(info->l3_forwarding), family(info->family), pkt(info),
flow_table(ftable), agent(a),
flow_source_vrf(-1), flow_dest_vrf(-1), nat_done(false),
nat_ip_saddr(), nat_ip_daddr(), nat_sport(0), nat_dport(0), nat_vrf(0),
nat_dest_vrf(0), dest_vrf(0), acl(NULL), ingress(false),
short_flow(false), local_flow(false), linklocal_flow(false),
tcp_ack(false), linklocal_bind_local_port(false),
linklocal_src_port_fd(kLinkLocalInvalidFd),
ecmp(false), in_component_nh_idx(-1), out_component_nh_idx(-1),
trap_rev_flow(false), fip_snat(false), fip_dnat(false), snat_fip(),
short_flow_reason(0), peer_vrouter(), tunnel_type(TunnelType::INVALID),
flood_unknown_unicast(false), bgp_router_service_flow(false),
alias_ip_flow(false), ttl(0), ecmp_component_affinity_nh(NULL) {
}
FlowTable *get_flow_table() const { return flow_table; }
static bool ComputeDirection(const Interface *intf);
void CheckLinkLocal(const PktInfo *pkt);
void LinkLocalServiceFromVm(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void LinkLocalServiceFromHost(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void LinkLocalServiceTranslate(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void BgpRouterServiceFromVm(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void BgpRouterServiceTranslate(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void FloatingIpSNat(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void FloatingIpDNat(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void IngressProcess(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void EgressProcess(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
void Add(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out);
bool Process(const PktInfo *pkt, PktControlInfo *in, PktControlInfo *out);
static bool GetIngressNwPolicyAclList(const Interface *intf,
const VnEntry *vn,
MatchPolicy *m_policy);
void RewritePktInfo(uint32_t index);
void GetEcmpCompositeAffinityNh();
bool VrfTranslate(const PktInfo *pkt, PktControlInfo *ctrl,
PktControlInfo *rev_flow, const IpAddress &src_ip,
bool nat_flow);
void UpdateFipStatsInfo(FlowEntry *flow, FlowEntry *rflow, const PktInfo *p,
const PktControlInfo *in, const PktControlInfo *o);
const NextHop *TunnelToNexthop(const PktInfo *pkt);
void ChangeVrf(const PktInfo *pkt, PktControlInfo *info,
const VrfEntry *vrf);
bool UnknownUnicastFlow(const PktInfo *p,
const PktControlInfo *in_info,
const PktControlInfo *out_info);
void GenerateTrafficSeen(const PktInfo *pkt, const PktControlInfo *in);
void ApplyFlowLimits(const PktControlInfo *in, const PktControlInfo *out);
void LinkLocalPortBind(const PktInfo *pkt, const PktControlInfo *in,
FlowEntry *flow);
bool IngressRouteAllowNatLookup(const AgentRoute *in_rt,
const AgentRoute *out_rt,
uint32_t sport,
uint32_t dport,
const Interface *intf);
bool EgressRouteAllowNatLookup(const AgentRoute *in_rt,
const AgentRoute *out_rt,
uint32_t sport,
uint32_t dport,
const Interface *intf);
public:
void UpdateRoute(const AgentRoute **rt, const VrfEntry *vrf,
const IpAddress &addr, const MacAddress &mac,
FlowRouteRefMap &ref_map);
uint8_t RouteToPrefixLen(const AgentRoute *route);
void CalculatePort(const PktInfo *p, const Interface *intf);
void SetPktInfo(boost::shared_ptr<PktInfo> info);
bool RouteAllowNatLookupCommon(const AgentRoute *rt,
uint32_t sport,
uint32_t dport,
const Interface *intf);
bool IsBgpRouterServiceRoute(const AgentRoute *in_rt,
const AgentRoute *out_rt,
const Interface *intf,
uint32_t sport,
uint32_t dport);
void UpdateEvictedFlowStats(const PktInfo *pkt);
bool l3_flow;
Address::Family family;
boost::shared_ptr<PktInfo> pkt;
FlowTable *flow_table;
Agent *agent;
uint32_t flow_source_vrf;
uint32_t flow_dest_vrf;
// map for references to the routes which were ignored due to more specific
// route this will be used to trigger flow re-compute to use more specific
// on route add. key for the map is vrf and data is prefix length
FlowRouteRefMap flow_source_plen_map;
FlowRouteRefMap flow_dest_plen_map;
// NAT addresses
bool nat_done;
IpAddress nat_ip_saddr;
IpAddress nat_ip_daddr;
uint32_t nat_sport;
uint32_t nat_dport;
// VRF for matching the NAT flow
uint32_t nat_vrf;
// Modified VRF for the NAT flow
// After flow processing, packet is assigned this VRF
uint32_t nat_dest_vrf;
// Modified VRF for the forward flow
// After flow processing, packet is assigned this VRF
uint32_t dest_vrf;
// Intermediate fields used in creating flows
const AclDBEntry *acl;
// Ingress flow or egress flow
bool ingress;
bool short_flow;
bool local_flow;
bool linklocal_flow;
bool tcp_ack;
bool linklocal_bind_local_port;
int linklocal_src_port_fd;
bool ecmp;
uint32_t in_component_nh_idx;
uint32_t out_component_nh_idx;
bool trap_rev_flow;
// Following fields are required for FIP stats accounting
bool fip_snat;
bool fip_dnat;
IpAddress snat_fip;
uint16_t short_flow_reason;
std::string peer_vrouter;
TunnelType tunnel_type;
// flow entry being revaluated or trapped for ECMP resolution
FlowEntry *flow_entry;
bool flood_unknown_unicast;
//BGP router service info
bool bgp_router_service_flow;
// Alias IP flow
bool alias_ip_flow;
//TTL of nat'd flow especially bgp-service flows
uint8_t ttl;
// Affinity to Ecmp component NH.
// When a packet is trapped for ECMP Resolution its possible that flow is
// transition from Non-ECMP to ECMP. In that case, the ECMP index must be
// be set to unicast-nh used when flow is non-ECMP. The affinity-nh
// is set in this case.
const NextHop *ecmp_component_affinity_nh;
};
#endif // __agent_pkt_flow_info_h_