Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "kstate.h" 6 : #include "nh_kstate.h" 7 : #include "vr_nexthop.h" 8 : #include <net/ethernet.h> 9 : #include <netinet/if_ether.h> 10 : #include <iomanip> 11 : #include <sstream> 12 : 13 : using namespace std; 14 : 15 0 : NHKState::NHKState(KNHResp *obj, const std::string &resp_ctx, 16 0 : vr_nexthop_req &req, int id) 17 0 : : KState(resp_ctx, obj) { 18 : 19 0 : req.set_nhr_id(id); 20 0 : if (id >= 0) { 21 0 : req.set_h_op(sandesh_op::GET); 22 : } else { 23 0 : req.set_h_op(sandesh_op::DUMP); 24 0 : req.set_nhr_marker(-1); 25 : } 26 0 : } 27 : 28 0 : void NHKState::SendNextRequest() { 29 0 : vr_nexthop_req req; 30 0 : req.set_nhr_id(0); 31 0 : req.set_h_op(sandesh_op::DUMP); 32 0 : int32_t idx = boost::any_cast<int32_t>(more_context_); 33 0 : req.set_nhr_marker(idx); 34 0 : EncodeAndSend(req); 35 0 : } 36 : 37 0 : void NHKState::Handler() { 38 0 : KNHResp *resp = static_cast<KNHResp *>(response_object_); 39 0 : if (resp) { 40 0 : if (MoreData()) { 41 : /* There are more nexthops in Kernel. We need to query them from 42 : * Kernel and send it to Sandesh. 43 : */ 44 0 : SendResponse(); 45 0 : SendNextRequest(); 46 : } else { 47 0 : resp->set_context(response_context_); 48 0 : resp->Response(); 49 0 : more_context_ = boost::any(); 50 : } 51 : } 52 0 : } 53 : 54 0 : void NHKState::SendResponse() { 55 : 56 0 : KNHResp *resp = static_cast<KNHResp *>(response_object_); 57 0 : resp->set_context(response_context_); 58 0 : resp->set_more(true); 59 0 : resp->Response(); 60 : 61 0 : response_object_ = new KNHResp(); 62 0 : } 63 : 64 : 65 0 : const string NHKState::TypeToString(int nh_type) const { 66 0 : unsigned short type = nh_type; 67 0 : switch(type) { 68 0 : case NH_ENCAP: 69 0 : return "ENCAP"; 70 0 : case NH_TUNNEL: 71 0 : return "TUNNEL"; 72 0 : case NH_DISCARD: 73 0 : return "DISCARD"; 74 0 : case NH_RCV: 75 0 : return "RECEIVE"; 76 0 : case NH_RESOLVE: 77 0 : return "RESOLVE"; 78 0 : case NH_COMPOSITE: 79 0 : return "COMPOSITE"; 80 0 : case NH_DEAD: 81 0 : return "DEAD"; 82 0 : default: 83 0 : return "INVALID"; 84 : } 85 : } 86 : 87 0 : const string NHKState::FamilyToString(int nh_family) const { 88 0 : unsigned family = nh_family; 89 0 : switch(family) { 90 0 : case AF_INET: 91 0 : return "AF_INET"; 92 0 : case AF_INET6: 93 0 : return "AF_INET6"; 94 0 : default: 95 0 : return "INVALID"; 96 : } 97 : } 98 : 99 0 : const string NHKState::EncapFamilyToString(int nh_family) const { 100 0 : unsigned family = nh_family; 101 0 : switch(family) { 102 0 : case ETHERTYPE_ARP: 103 0 : return "ETH_P_ARP"; 104 0 : case 0: 105 0 : return "NO_ENCAP"; 106 0 : default: 107 0 : return "INVALID"; 108 : } 109 : } 110 : 111 0 : const string NHKState::EncapToString(const vector<signed char> &encap) const { 112 0 : ostringstream strm; 113 : uint8_t ubyte; 114 0 : vector<signed char>::const_iterator it = encap.begin(); 115 0 : strm << hex << setfill('0'); 116 0 : while(it != encap.end()) { 117 0 : ubyte = (uint8_t) *it; 118 0 : strm << setw(2) << (int)ubyte; 119 0 : ++it; 120 : } 121 0 : return strm.str(); 122 0 : } 123 : 124 0 : const string NHKState::FlagsToString(uint32_t flags) const { 125 0 : string flag_str, policy_str("POLICY "), gre_str("TUNNEL_GRE "); 126 0 : string fabric_multicast("FABRIC_MULTICAST"); 127 0 : string l2_multicast("L2_MULTICAST"); 128 0 : string l3_multicast("L3_MULTICAST"); 129 0 : string multi_proto_multicast("MULTI_PROTO_MULTICAST"); 130 0 : string ecmp("ECMP"); 131 0 : string multicast_encap("MULTICAST_ENCAP"); 132 0 : string mpls_udp_str("TUNNEL_MPLS_UDP "); 133 0 : string udp_str("TUNNEL_UDP "), sip_copy("TUNNEL_SIP_COPY "); 134 0 : bool assigned = false; 135 : 136 0 : if (flags & NH_FLAG_VALID) { 137 0 : flag_str.assign("VALID "); 138 0 : assigned = true; 139 : } 140 0 : if (flags & NH_FLAG_POLICY_ENABLED) { 141 0 : if (assigned) { 142 0 : flag_str.append("| " + policy_str); 143 : } else { 144 0 : flag_str.assign(policy_str); 145 0 : assigned = true; 146 : } 147 : } 148 0 : if (flags & NH_FLAG_TUNNEL_GRE) { 149 0 : if (assigned) { 150 0 : flag_str.append("| " + gre_str); 151 : } else { 152 0 : flag_str.assign(gre_str); 153 0 : assigned = true; 154 : } 155 : } 156 0 : if (flags & NH_FLAG_TUNNEL_UDP) { 157 0 : if (assigned) { 158 0 : flag_str.append("| " + udp_str); 159 : } else { 160 0 : flag_str.assign(udp_str); 161 0 : assigned = true; 162 : } 163 : } 164 0 : if (flags & NH_FLAG_TUNNEL_UDP_MPLS) { 165 0 : if (assigned) { 166 0 : flag_str.append("| " + mpls_udp_str); 167 : } else { 168 0 : flag_str.assign(mpls_udp_str); 169 0 : assigned = true; 170 : } 171 : } 172 : 173 0 : if (flags & NH_FLAG_COMPOSITE_ECMP) { 174 0 : if (assigned) { 175 0 : flag_str.append("| " + ecmp); 176 : } else { 177 0 : flag_str.assign(ecmp); 178 0 : assigned = true; 179 : } 180 : } 181 : 182 0 : if (flags & NH_FLAG_COMPOSITE_FABRIC) { 183 0 : if (assigned) { 184 0 : flag_str.append("| " + fabric_multicast); 185 : } else { 186 0 : flag_str.assign(fabric_multicast); 187 0 : assigned = true; 188 : } 189 : } 190 : 191 0 : if (flags & NH_FLAG_TUNNEL_SIP_COPY) { 192 0 : if (assigned) { 193 0 : flag_str.append("| " + sip_copy); 194 : } else { 195 0 : flag_str.assign(sip_copy); 196 0 : assigned = true; 197 : } 198 : } 199 : 200 0 : if (!assigned) { 201 0 : return "NIL"; 202 : } 203 0 : return flag_str; 204 0 : } 205 : 206 0 : void NHKState::SetComponentNH(vr_nexthop_req *req, KNHInfo &info) { 207 0 : std::vector<KComponentNH> comp_nh_list; 208 0 : KComponentNH comp_nh; 209 : 210 0 : if (req->get_nhr_type() != NH_COMPOSITE) { 211 0 : return; 212 : } 213 : 214 0 : const std::vector<int32_t> nh_list = req->get_nhr_nh_list(); 215 0 : const std::vector<int32_t> label_list = req->get_nhr_label_list(); 216 : 217 0 : for (uint32_t i = 0; i < nh_list.size(); i++) { 218 0 : comp_nh.set_nh_id(nh_list[i]); 219 0 : comp_nh.set_label(label_list[i]); 220 0 : comp_nh_list.push_back(comp_nh); 221 : } 222 0 : info.set_component_nh(comp_nh_list); 223 0 : }