Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef vnsw_agent_ndp_entry_hpp 6 : #define vnsw_agent_ndp_entry_hpp 7 : 8 : 9 : #include "base/timer.h" 10 : #include <boost/statechart/state_machine.hpp> 11 : #include <netinet/icmp6.h> 12 : #include "services/icmpv6_handler.h" 13 : 14 : namespace sc = boost::statechart; 15 : class NdpEntry; 16 : 17 : namespace fsm { 18 : struct NoState; 19 : } 20 : 21 : struct NdpKey { 22 10 : NdpKey(Ip6Address addr, const VrfEntry *ventry) : ip(addr), vrf(ventry) {}; 23 0 : NdpKey(const NdpKey &key) : ip(key.ip), vrf(key.vrf) {}; 24 0 : bool operator <(const NdpKey &rhs) const { 25 0 : if (vrf != rhs.vrf) 26 0 : return vrf < rhs.vrf; 27 0 : return (ip < rhs.ip); 28 : } 29 : 30 : Ip6Address ip; 31 : const VrfEntry *vrf; 32 : }; 33 : 34 : typedef boost::function<bool(NdpEntry*)> EvValidate; 35 : 36 : // Represents each NDP entry maintained by the Icmpv6 module 37 : class NdpEntry : public sc::state_machine<NdpEntry, fsm::NoState> { 38 : public: 39 : NdpEntry(boost::asio::io_context &io, Icmpv6Handler *handler, 40 : NdpKey &key, const VrfEntry *vrf, const Interface *itf); 41 : virtual ~NdpEntry(); 42 : 43 : typedef boost::function<void(void)> EventCB; 44 : 45 : static const int kMaxRetries; 46 : static const int kMaxUnicastRetries; 47 : 48 : enum State { 49 : NOSTATE = 0, 50 : INCOMPLETE = 1, 51 : REACHABLE = 2, 52 : STALE = 3, 53 : DELAY = 4, 54 : PROBE = 5 55 : }; 56 : 57 0 : const NdpKey &key() const { return key_; } 58 0 : const Interface *get_interface() const { return interface_.get(); } 59 : 60 : void StartRetransmitTimer(); 61 : void StartReachableTimer(); 62 : void StartDelayTimer(); 63 : void DeleteAllTimers(); 64 : 65 : const std::string &StateName() const; 66 : const std::string &LastStateName() const; 67 : 68 : struct EventContainer { 69 : boost::intrusive_ptr<const sc::event_base> event; 70 : EvValidate validate; 71 : }; 72 : 73 0 : int retry_count() const { return retry_count_; } 74 0 : void retry_count_inc() { retry_count_++; } 75 0 : void retry_count_clear() { retry_count_ = 0; } 76 15 : void retry_count_set(int rc) { retry_count_ = rc; } 77 : 78 : int retransmit_time() const { return retransmit_time_; } 79 : void set_retransmit_time(int t) { retransmit_time_ = t; } 80 : int reachable_time() const { return reachable_time_; } 81 : void set_reachable_time(int t) { reachable_time_ = t; } 82 : 83 : void set_state(State state); 84 47 : State get_state() const { return state_; } 85 : const std::string last_state_change_at() const; 86 : const uint64_t last_state_change_usecs_at() const; 87 : void set_last_event(const std::string &event); 88 : const std::string &last_event() const { return last_event_; } 89 0 : MacAddress mac() const { return mac_; } 90 0 : void set_mac(MacAddress mac) { mac_ = mac; } 91 : 92 : void set_last_notification_in(int code, int subcode, 93 : const std::string &reason); 94 : void set_last_notification_out(int code, int subcode, 95 : const std::string &reason); 96 : void reset_last_info(); 97 : void LogEvent(std::string event_name, std::string msg, 98 : SandeshLevel::type log_level = SandeshLevel::SYS_DEBUG); 99 : bool RetransmitTimerExpired(); 100 : bool ReachableTimerExpired(); 101 : bool DelayTimerExpired(); 102 : bool EnqueuePktOut(); 103 : bool EnqueueTestStateChange(State state, int retry_count); 104 : bool EnqueueRetransmitTimerExpired(); 105 : bool EnqueueReachableTimerExpired(); 106 : bool EnqueueDelayTimerExpired(); 107 : bool EnqueueNaIn(nd_neighbor_advert na, MacAddress mac); 108 : bool EnqueueSolNaIn(nd_neighbor_advert na, MacAddress mac); 109 : bool EnqueueUnsolNaIn(nd_neighbor_advert na, MacAddress mac); 110 : bool EnqueueNsIn(nd_neighbor_solicit ns, MacAddress mac); 111 : 112 : template <typename Ev> bool Enqueue(const Ev &event); 113 : bool DequeueEvent(EventContainer ec); 114 : void DequeueEventDone(bool done); 115 : void UpdateFlapCount(); 116 3 : Timer* retransmit_timer() { return retransmit_timer_; }; 117 1 : Timer* reachable_timer() { return reachable_timer_; }; 118 1 : Timer* delay_timer() { return delay_timer_; }; 119 : 120 : bool DeleteNdpRoute(); 121 : bool IsResolved(); 122 : void Resync(bool policy, const VnListType &vnlist, 123 : const SecurityGroupList &sg, 124 : const TagList &tag); 125 : void HandleNsRequest(nd_neighbor_solicit ns, MacAddress mac); 126 : void SendNeighborSolicit(bool send_unicast=false); 127 : void SendNeighborAdvert(bool solicited); 128 : private: 129 : void AddNdpRoute(bool resolved); 130 : bool IsDerived(); 131 : 132 : WorkQueue<EventContainer> work_queue_; 133 : Timer *delay_timer_; 134 : Timer *retransmit_timer_; 135 : Timer *reachable_timer_; 136 : int retransmit_time_; 137 : int delay_time_; 138 : int reachable_time_; 139 : int retry_count_; 140 : bool deleted_; 141 : State state_; 142 : State last_state_; 143 : MacAddress mac_; 144 : std::string last_event_; 145 : uint64_t last_event_at_; 146 : uint64_t last_state_change_at_; 147 : std::pair<int, int> last_notification_in_; 148 : std::string last_notification_in_error_; 149 : uint64_t last_notification_in_at_; 150 : std::pair<int, int> last_notification_out_; 151 : std::string last_notification_out_error_; 152 : uint64_t last_notification_out_at_; 153 : boost::asio::io_context &io_; 154 : NdpKey key_; 155 : const VrfEntry *nh_vrf_; 156 : boost::intrusive_ptr<Icmpv6Handler> handler_; 157 : InterfaceConstRef interface_; 158 : DISALLOW_COPY_AND_ASSIGN(NdpEntry); 159 : }; 160 : 161 : #endif // vnsw_agent_ndp_entry_hpp