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