OpenSDN source code
icmpv6_proto.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef vnsw_agent_icmpv6_proto_h
6 #define vnsw_agent_icmpv6_proto_h
7 
8 #include <atomic>
9 
10 #include "pkt/proto.h"
12 #include "services/ndp_entry.h"
13 
14 #define ICMP_PKT_SIZE 1024
15 #define IPV6_ALL_NODES_ADDRESS "FF02::1"
16 #define IPV6_ALL_ROUTERS_ADDRESS "FF02::2"
17 #define PKT0_LINKLOCAL_ADDRESS "FE80::5E00:0100"
18 
19 #define NDP_TRACE(obj, ...) \
20 do { \
21  Ndp##obj::TraceMsg(Icmpv6TraceBuf, __FILE__, __LINE__, ##__VA_ARGS__); \
22 } while (false) \
23 
24 #define ICMPV6_TRACE(obj, arg) \
25 do { \
26  std::ostringstream _str; \
27  _str << arg; \
28  Icmpv6##obj::TraceMsg(Icmpv6TraceBuf, __FILE__, __LINE__, _str.str()); \
29 } while (false) \
30 
31 class Icmpv6VrfState;
33 
34 class Icmpv6Proto : public Proto {
35 public:
36  static const uint32_t kRouterAdvertTimeout = 30000; // milli seconds
37  static const uint16_t kMaxRetries = 8;
38  static const uint32_t kRetryTimeout = 2000; // milli seconds
39  static const uint32_t kAgingTimeout = (5 * 60 * 1000); // milli seconds
40 
45  };
46 
49  : InterTaskMsg(msg), key(akey), interface_(itf) {}
51  const VrfEntry *vrf, InterfaceConstRef itf) :
52  InterTaskMsg(msg), key(ip, vrf), interface_(itf) {}
53 
56  };
57 
58  struct Icmpv6Stats {
59  Icmpv6Stats() { Reset(); }
60  void Reset() {
66  }
67 
72  uint32_t icmpv6_drop_;
77  };
78 
79  typedef std::map<VmInterface *, Icmpv6Stats> VmInterfaceMap;
80  typedef std::pair<VmInterface *, Icmpv6Stats> VmInterfacePair;
81  typedef std::map<NdpKey, NdpEntry *> NdpCache;
82  typedef std::pair<NdpKey, NdpEntry *> NdpCachePair;
83  typedef std::map<NdpKey, NdpEntry *>::iterator NdpIterator;
84  typedef std::set<NdpKey> NdpKeySet;
85  typedef std::set<NdpEntry *> NdpEntrySet;
86  typedef std::map<NdpKey, NdpEntrySet> UnsolNaCache;
87  typedef std::pair<NdpKey, NdpEntrySet> UnsolNaCachePair;
88  typedef std::map<NdpKey, NdpEntrySet>::iterator UnsolNaIterator;
89 
94  };
95  typedef std::map<uint32_t, InterfaceNdpInfo> InterfaceNdpMap;
96  typedef std::pair<uint32_t, InterfaceNdpInfo> InterfaceNdpPair;
97 
98  void Shutdown();
99  Icmpv6Proto(Agent *agent, boost::asio::io_context &io);
100  virtual ~Icmpv6Proto();
101  ProtoHandler *AllocProtoHandler(boost::shared_ptr<PktInfo> info,
102  boost::asio::io_context &io);
103  void VrfNotify(DBTablePartBase *part, DBEntryBase *entry);
104  void VnNotify(DBEntryBase *entry);
105  void InterfaceNotify(DBEntryBase *entry);
106  void NexthopNotify(DBEntryBase *entry);
108  const VrfEntry *vrf, InterfaceConstRef itf);
109 
111 
121  const Icmpv6Stats &GetStats() const { return stats_; }
122  Icmpv6Stats *VmiToIcmpv6Stats(VmInterface *i);
123  void ClearStats() { stats_.Reset(); }
126 
128  uint32_t ip_fabric_interface_index() const {
130  }
133  }
135  void set_ip_fabric_interface_index(uint32_t ind) {
137  }
140  }
141 
142  bool AddNdpEntry(NdpEntry *entry);
143  bool DeleteNdpEntry(NdpEntry *entry);
144  NdpEntry *FindNdpEntry(const NdpKey &key);
145  std::size_t GetNdpCacheSize() { return ndp_cache_.size(); }
146  const NdpCache& ndp_cache() { return ndp_cache_; }
149 
150  void AddUnsolNaEntry(NdpKey &key);
151  void DeleteUnsolNaEntry(NdpEntry *entry);
152  void HandlePathPreferenceNA(const VrfEntry*, uint32_t, IpAddress);
154  NdpEntry* UnsolNaEntry (const NdpKey &key, const Interface *intf);
156  UnsolNaEntryIterator(const NdpKey &key, bool *key_valid);
158  return vrf_table_listener_id_;
159  }
160 
161 private:
168  bool HandlePacket();
172  InterfaceConstRef itf);
173  // handler to send router advertisements and neighbor solicits
174  boost::scoped_ptr<Icmpv6Handler> icmpv6_handler_;
183 };
184 
185 class Icmpv6VrfState : public DBState {
186 public:
187  typedef std::map<const IpAddress,
189  typedef std::pair<const IpAddress,
191 
193  AgentRouteTable *table, AgentRouteTable *evpn_table);
194  ~Icmpv6VrfState();
195  Agent *agent() const { return agent_; }
196  Icmpv6Proto * icmp_proto() const { return icmp_proto_; }
199  }
202  }
204  void set_default_routes_added(bool value) { default_routes_added_ = value; }
205 
206  void RouteUpdate(DBTablePartBase *part, DBEntryBase *entry);
207  void EvpnRouteUpdate(DBTablePartBase *part, DBEntryBase *entry);
208  void ManagedDelete() { deleted_ = true;}
209  void Delete();
210  bool DeleteRouteState(DBTablePartBase *part, DBEntryBase *entry);
212  bool PreWalkDone(DBTableBase *partition);
213  static void WalkDone(DBTableBase *partition, Icmpv6VrfState *state);
214  bool deleted() const {return deleted_;}
215 
217  void Erase(const IpAddress &ip);
219  return icmpv6_path_preference_map_[ip];
220  }
221 
222  bool l3_walk_completed() const {
223  return l3_walk_completed_;
224  }
225 
226  bool evpn_walk_completed() const {
227  return evpn_walk_completed_;
228  }
231  }
233  return evpn_walk_ref_;
234  }
235 
236 private:
246  bool deleted_;
254 };
255 
257  uint32_t ns_try_count;
258  uint32_t ns_send_count;
259  uint32_t ns_retry_count;
261  ns_retry_count(0) {
262  }
263 };
264 
266 public:
267  static const uint32_t kMaxRetry = 30 * 5; //retries upto 5 minutes,
268  //30 tries/per minutes
269  static const uint32_t kTimeout = 2000;
270 
271  static const uint32_t kTimeoutMultiplier = 5;
272 
273  static const uint32_t kNSTryCount = 9;
274 
275  typedef std::map<uint32_t, InterfaceIcmpv6PathPreferenceInfo> WaitForTrafficIntfMap;
276  typedef std::set<uint32_t> NDTransmittedIntfMap;
277 
279  IpAddress vm_ip_addr, uint8_t plen);
281  bool SendNeighborSolicit();
282  bool SendNeighborSolicit(WaitForTrafficIntfMap &wait_for_traffic_map,
283  NDTransmittedIntfMap &nd_transmitted_map);
284  void SendNeighborSolicitForAllIntf(const AgentRoute *route);
285  void StartTimer();
286  void HandleNA(uint32_t itf);
288  return vrf_state_;
289  }
290 
291  const IpAddress& ip() const {
292  return vm_ip_;
293  }
294 
295  MacAddress mac(void) const { return mac_; }
296 
297  bool IntfPresentInIpMap(uint32_t id) {
298  if (l3_wait_for_traffic_map_.find(id) ==
299  l3_wait_for_traffic_map_.end()) {
300  return false;
301  }
302  return true;
303  }
304 
305  bool IntfPresentInEvpnMap(uint32_t id) {
306  if (evpn_wait_for_traffic_map_.find(id) ==
308  return false;
309  }
310  return true;
311  }
312 
313  uint32_t IntfRetryCountInIpMap(uint32_t id) {
314  return l3_wait_for_traffic_map_[id].ns_retry_count;
315  }
316 
317  uint32_t IntfRetryCountInEvpnMap(uint32_t id) {
318  return evpn_wait_for_traffic_map_[id].ns_retry_count;
319  }
320 
321 private:
326  uint32_t vrf_id_;
329  uint8_t plen_;
333  std::atomic<int> refcount_;
334 };
335 
336 typedef boost::intrusive_ptr<Icmpv6PathPreferenceState>
338 
341 
342 class Icmpv6RouteState : public DBState {
343 public:
344  Icmpv6RouteState(Icmpv6VrfState *vrf_state, uint32_t vrf_id,
345  IpAddress vm_ip_addr, uint8_t plen);
347  void SendNeighborSolicitForAllIntf(const AgentRoute *route);
348 private:
350 };
351 #endif // vnsw_agent_icmpv6_proto_h
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
boost::asio::ip::address IpAddress
Definition: address.h:13
boost::intrusive_ptr< const Interface > InterfaceConstRef
Definition: agent.h:51
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge,...
Definition: agent_route.h:109
Base class for all Route entries in agent.
Definition: agent_route.h:224
Definition: agent.h:360
int ListenerId
Definition: db_table.h:62
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
Definition: db_table.h:169
static const uint32_t kTimeoutMultiplier
Definition: icmpv6_proto.h:271
Icmpv6PathPreferenceState(Icmpv6VrfState *vrf_state, uint32_t vrf_id, IpAddress vm_ip_addr, uint8_t plen)
friend void intrusive_ptr_release(Icmpv6PathPreferenceState *ps)
MacAddress mac(void) const
Definition: icmpv6_proto.h:295
WaitForTrafficIntfMap l3_wait_for_traffic_map_
Definition: icmpv6_proto.h:331
std::map< uint32_t, InterfaceIcmpv6PathPreferenceInfo > WaitForTrafficIntfMap
Definition: icmpv6_proto.h:275
friend void intrusive_ptr_add_ref(Icmpv6PathPreferenceState *ps)
Icmpv6VrfState * vrf_state_
Definition: icmpv6_proto.h:324
bool IntfPresentInEvpnMap(uint32_t id)
Definition: icmpv6_proto.h:305
static const uint32_t kNSTryCount
Definition: icmpv6_proto.h:273
std::atomic< int > refcount_
Definition: icmpv6_proto.h:333
const IpAddress & ip() const
Definition: icmpv6_proto.h:291
WaitForTrafficIntfMap evpn_wait_for_traffic_map_
Definition: icmpv6_proto.h:332
uint32_t IntfRetryCountInIpMap(uint32_t id)
Definition: icmpv6_proto.h:313
void HandleNA(uint32_t itf)
bool IntfPresentInIpMap(uint32_t id)
Definition: icmpv6_proto.h:297
static const uint32_t kTimeout
Definition: icmpv6_proto.h:269
void SendNeighborSolicitForAllIntf(const AgentRoute *route)
uint32_t IntfRetryCountInEvpnMap(uint32_t id)
Definition: icmpv6_proto.h:317
std::set< uint32_t > NDTransmittedIntfMap
Definition: icmpv6_proto.h:276
static const uint32_t kMaxRetry
Definition: icmpv6_proto.h:267
Icmpv6VrfState * vrf_state()
Definition: icmpv6_proto.h:287
void DeleteUnsolNaEntry(NdpEntry *entry)
std::map< NdpKey, NdpEntry * >::iterator NdpIterator
Definition: icmpv6_proto.h:83
DBTableBase::ListenerId vrf_table_listener_id() const
Definition: icmpv6_proto.h:157
std::pair< NdpKey, NdpEntrySet > UnsolNaCachePair
Definition: icmpv6_proto.h:87
void ClearStats()
Definition: icmpv6_proto.h:123
Interface * ip_fabric_interface_
Definition: icmpv6_proto.h:181
virtual ~Icmpv6Proto()
Definition: icmpv6_proto.cc:40
VmInterfaceMap vm_interfaces_
Definition: icmpv6_proto.h:164
uint32_t ip_fabric_interface_index() const
Definition: icmpv6_proto.h:128
void VrfNotify(DBTablePartBase *part, DBEntryBase *entry)
Icmpv6Proto(Agent *agent, boost::asio::io_context &io)
Definition: icmpv6_proto.cc:13
static const uint16_t kMaxRetries
Definition: icmpv6_proto.h:37
DISALLOW_COPY_AND_ASSIGN(Icmpv6Proto)
InterfaceNdpMap interface_ndp_map_
Definition: icmpv6_proto.h:167
void IncrementStatsRouterSolicit(VmInterface *vmi)
Icmpv6Stats * VmiToIcmpv6Stats(VmInterface *i)
std::map< uint32_t, InterfaceNdpInfo > InterfaceNdpMap
Definition: icmpv6_proto.h:95
boost::scoped_ptr< Icmpv6Handler > icmpv6_handler_
Definition: icmpv6_proto.h:174
static const uint32_t kRetryTimeout
Definition: icmpv6_proto.h:38
Icmpv6VrfState * CreateAndSetVrfState(VrfEntry *vrf)
Definition: icmpv6_proto.cc:56
void IncrementStatsNeighborAdvertUnSolicited(VmInterface *vmi)
const InterfaceNdpMap & interface_ndp_map()
Definition: icmpv6_proto.h:148
bool ValidateAndClearVrfState(VrfEntry *vrf, Icmpv6VrfState *state)
std::pair< NdpKey, NdpEntry * > NdpCachePair
Definition: icmpv6_proto.h:82
Icmpv6Proto::UnsolNaIterator UnsolNaEntryIterator(const NdpKey &key, bool *key_valid)
bool DeleteNdpEntry(NdpEntry *entry)
NdpEntry * FindNdpEntry(const NdpKey &key)
const UnsolNaCache & unsol_na_cache()
Definition: icmpv6_proto.h:147
std::map< NdpKey, NdpEntrySet >::iterator UnsolNaIterator
Definition: icmpv6_proto.h:88
void IncrementStatsPingResponse(VmInterface *vmi)
void IncrementStatsRouterAdvert(VmInterface *vmi)
ProtoHandler * AllocProtoHandler(boost::shared_ptr< PktInfo > info, boost::asio::io_context &io)
Definition: icmpv6_proto.cc:51
NdpEntry * UnsolNaEntry(const NdpKey &key, const Interface *intf)
DBTableBase::ListenerId vrf_table_listener_id_
Definition: icmpv6_proto.h:176
Timer * timer_
Definition: icmpv6_proto.h:162
std::set< NdpEntry * > NdpEntrySet
Definition: icmpv6_proto.h:85
bool HandlePacket()
DBTableBase::ListenerId nexthop_listener_id_
Definition: icmpv6_proto.h:178
void SendIcmpv6Ipc(Icmpv6Proto::Icmpv6MsgType type, Ip6Address ip, const VrfEntry *vrf, InterfaceConstRef itf)
void IncrementStatsPingRequest(VmInterface *vmi)
std::map< NdpKey, NdpEntry * > NdpCache
Definition: icmpv6_proto.h:81
NdpCache ndp_cache_
Definition: icmpv6_proto.h:165
bool HandleMessage()
DBTableBase::ListenerId interface_listener_id_
Definition: icmpv6_proto.h:177
static const uint32_t kAgingTimeout
Definition: icmpv6_proto.h:39
void IncrementStatsDrop()
Definition: icmpv6_proto.h:116
void IncrementStatsNeighborAdvertSolicited(VmInterface *vmi)
std::map< NdpKey, NdpEntrySet > UnsolNaCache
Definition: icmpv6_proto.h:86
std::pair< uint32_t, InterfaceNdpInfo > InterfaceNdpPair
Definition: icmpv6_proto.h:96
bool AddNdpEntry(NdpEntry *entry)
void VnNotify(DBEntryBase *entry)
Definition: icmpv6_proto.cc:69
void set_ip_fabric_interface(Interface *itf)
Definition: icmpv6_proto.h:134
void AddUnsolNaEntry(NdpKey &key)
const NdpCache & ndp_cache()
Definition: icmpv6_proto.h:146
MacAddress ip_fabric_interface_mac_
Definition: icmpv6_proto.h:180
std::pair< VmInterface *, Icmpv6Stats > VmInterfacePair
Definition: icmpv6_proto.h:80
const MacAddress & ip_fabric_interface_mac() const
Definition: icmpv6_proto.h:131
Interface * ip_fabric_interface() const
Definition: icmpv6_proto.h:127
void set_ip_fabric_interface_index(uint32_t ind)
Definition: icmpv6_proto.h:135
void InterfaceNotify(DBEntryBase *entry)
NdpEntry * FindUnsolNaEntry(NdpKey &key)
void set_ip_fabric_interface_mac(const MacAddress &mac)
Definition: icmpv6_proto.h:138
UnsolNaCache unsol_na_cache_
Definition: icmpv6_proto.h:166
void HandlePathPreferenceNA(const VrfEntry *, uint32_t, IpAddress)
static const uint32_t kRouterAdvertTimeout
Definition: icmpv6_proto.h:36
std::set< NdpKey > NdpKeySet
Definition: icmpv6_proto.h:84
uint32_t ip_fabric_interface_index_
Definition: icmpv6_proto.h:179
Icmpv6Stats stats_
Definition: icmpv6_proto.h:163
void IncrementStatsNeighborSolicited(VmInterface *vmi)
std::map< VmInterface *, Icmpv6Stats > VmInterfaceMap
Definition: icmpv6_proto.h:79
const VmInterfaceMap & vm_interfaces()
Definition: icmpv6_proto.h:110
void NexthopNotify(DBEntryBase *entry)
void IncrementStatsNeighborSolicit(VmInterface *vmi)
DBTableBase::ListenerId vn_table_listener_id_
Definition: icmpv6_proto.h:175
void Shutdown()
Definition: icmpv6_proto.cc:43
const Icmpv6Stats & GetStats() const
Definition: icmpv6_proto.h:121
std::size_t GetNdpCacheSize()
Definition: icmpv6_proto.h:145
Icmpv6RouteState(Icmpv6VrfState *vrf_state, uint32_t vrf_id, IpAddress vm_ip_addr, uint8_t plen)
void SendNeighborSolicitForAllIntf(const AgentRoute *route)
Icmpv6PathPreferenceStatePtr icmpv6_path_preference_state_
Definition: icmpv6_proto.h:349
Icmpv6PathPreferenceState * Get(const IpAddress ip)
Definition: icmpv6_proto.h:218
DBTable::DBTableWalkRef evpn_walk_ref_
Definition: icmpv6_proto.h:249
DISALLOW_COPY_AND_ASSIGN(Icmpv6VrfState)
bool l3_walk_completed_
Definition: icmpv6_proto.h:251
static void WalkDone(DBTableBase *partition, Icmpv6VrfState *state)
void Erase(const IpAddress &ip)
bool PreWalkDone(DBTableBase *partition)
bool default_routes_added() const
Definition: icmpv6_proto.h:203
LifetimeRef< Icmpv6VrfState > table_delete_ref_
Definition: icmpv6_proto.h:244
Icmpv6PathPreferenceStateMap icmpv6_path_preference_map_
Definition: icmpv6_proto.h:250
void set_route_table_listener_id(const DBTableBase::ListenerId &id)
Definition: icmpv6_proto.h:197
AgentRouteTable * rt_table_
Definition: icmpv6_proto.h:240
void set_evpn_route_table_listener_id(const DBTableBase::ListenerId &id)
Definition: icmpv6_proto.h:200
DBTable::DBTableWalkRef managed_delete_walk_ref_
Definition: icmpv6_proto.h:248
bool default_routes_added_
Definition: icmpv6_proto.h:247
DBTable::DBTableWalkRef evpn_walk_ref()
Definition: icmpv6_proto.h:232
DBTable::DBTableWalkRef managed_delete_walk_ref()
Definition: icmpv6_proto.h:229
std::pair< const IpAddress, Icmpv6PathPreferenceState * > Icmpv6PathPreferenceStatePair
Definition: icmpv6_proto.h:190
VrfEntry * vrf_
Definition: icmpv6_proto.h:239
Agent * agent() const
Definition: icmpv6_proto.h:195
Icmpv6PathPreferenceState * Locate(const IpAddress &ip)
Icmpv6VrfState(Agent *agent, Icmpv6Proto *proto, VrfEntry *vrf, AgentRouteTable *table, AgentRouteTable *evpn_table)
AgentRouteTable * evpn_rt_table_
Definition: icmpv6_proto.h:241
Icmpv6Proto * icmp_proto_
Definition: icmpv6_proto.h:238
bool DeleteEvpnRouteState(DBTablePartBase *part, DBEntryBase *entry)
void RouteUpdate(DBTablePartBase *part, DBEntryBase *entry)
bool DeleteRouteState(DBTablePartBase *part, DBEntryBase *entry)
bool evpn_walk_completed_
Definition: icmpv6_proto.h:252
std::map< const IpAddress, Icmpv6PathPreferenceState * > Icmpv6PathPreferenceStateMap
Definition: icmpv6_proto.h:188
Icmpv6Proto * icmp_proto() const
Definition: icmpv6_proto.h:196
void set_default_routes_added(bool value)
Definition: icmpv6_proto.h:204
void EvpnRouteUpdate(DBTablePartBase *part, DBEntryBase *entry)
LifetimeRef< Icmpv6VrfState > evpn_table_delete_ref_
Definition: icmpv6_proto.h:245
DBTableBase::ListenerId evpn_route_table_listener_id_
Definition: icmpv6_proto.h:243
bool l3_walk_completed() const
Definition: icmpv6_proto.h:222
DBTableBase::ListenerId route_table_listener_id_
Definition: icmpv6_proto.h:242
bool evpn_walk_completed() const
Definition: icmpv6_proto.h:226
bool deleted() const
Definition: icmpv6_proto.h:214
void ManagedDelete()
Definition: icmpv6_proto.h:208
Definition: timer.h:57
Definition: vrf.h:89
void intrusive_ptr_release(Icmpv6PathPreferenceState *ps)
void intrusive_ptr_add_ref(Icmpv6PathPreferenceState *ps)
boost::intrusive_ptr< Icmpv6PathPreferenceState > Icmpv6PathPreferenceStatePtr
Definition: icmpv6_proto.h:337
uint8_t type
Definition: load_balance.h:2
Definition: io_utils.cc:11
Icmpv6Ipc(Icmpv6Proto::Icmpv6MsgType msg, NdpKey &akey, InterfaceConstRef itf)
Definition: icmpv6_proto.h:48
InterfaceConstRef interface_
Definition: icmpv6_proto.h:55
Icmpv6Ipc(Icmpv6Proto::Icmpv6MsgType msg, Ip6Address ip, const VrfEntry *vrf, InterfaceConstRef itf)
Definition: icmpv6_proto.h:50
uint32_t icmpv6_neighbor_advert_solicited_
Definition: icmpv6_proto.h:75
uint32_t icmpv6_neighbor_solicited_
Definition: icmpv6_proto.h:74
uint32_t icmpv6_neighbor_solicit_
Definition: icmpv6_proto.h:73
uint32_t icmpv6_neighbor_advert_unsolicited_
Definition: icmpv6_proto.h:76