OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ksync_sock_user.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #if defined(__linux__)
8 #include <linux/netlink.h>
9 #include <linux/rtnetlink.h>
10 #include <linux/genetlink.h>
11 #include <linux/sockios.h>
12 #endif
13 
14 #include <boost/bind.hpp>
15 
16 #include <base/logging.h>
17 #include <base/address_util.h>
18 #include <db/db.h>
19 #include <db/db_entry.h>
20 #include <db/db_table.h>
21 #include <db/db_table_partition.h>
22 
23 #include "ksync_index.h"
24 #include "ksync_entry.h"
25 #include "ksync_object.h"
26 #include "ksync_sock.h"
27 #include "ksync_sock_user.h"
28 
29 #include "nl_util.h"
30 #include "vr_genetlink.h"
31 #include "vr_message.h"
32 #include "vr_types.h"
33 #include "vr_defs.h"
34 #include "vr_interface.h"
35 #include <vector>
36 
38 vr_flow_entry *KSyncSockTypeMap::flow_table_;
40 using namespace boost::asio;
41 
42 int EncodeVrResponse(uint8_t *buf, int buf_len, uint32_t seq_num, int code) {
43  vr_response encoder;
44  int error = 0;
45 
46  encoder.set_h_op(sandesh_op::RESPONSE);
47  encoder.set_resp_code(code);
48  return encoder.WriteBinary(buf, buf_len, &error);
49 }
50 
51 void KSyncSockTypeMap::AddNetlinkTxBuff(struct nl_client *cl) {
52  tx_buff_list_.push_back(*cl);
53 }
54 
55 //process sandesh messages that are being sent from the agent
56 //this is used to store a local copy of what is being send to kernel
57 //Also handles bulk request messages.
58 void KSyncSockTypeMap::ProcessSandesh(const uint8_t *parse_buf, size_t buf_len,
59  KSyncUserSockContext *ctx) {
60  int decode_len;
61  uint8_t *decode_buf;
62 
63  // Ensure that tx_buff_list is empty
64  assert(tx_buff_list_.size() == 0);
65 
66  //parse sandesh
67  int err = 0;
68  int decode_buf_len = buf_len;
69  decode_buf = (uint8_t *)(parse_buf);
70  while(decode_buf_len > 0) {
71  decode_len = Sandesh::ReceiveBinaryMsgOne(decode_buf, decode_buf_len,
72  &err, ctx);
73  if (decode_len < 0) {
74  LOG(DEBUG, "Incorrect decode len " << decode_len);
75  break;
76  }
77  decode_buf += decode_len;
78  decode_buf_len -= decode_len;
79  }
80 
81  PurgeTxBuffer();
82 }
83 
85  // All responses are stored in tx_buff_list_
86  // Make io-vector of all responses and transmit them
87  // If there are more than one responses, they are sent as NETLINK MULTI
88  // messages
89  uint32_t count = 0;
90  KSyncBufferList iovec;
91  struct nlmsghdr *last_nlh = NULL;
92  std::vector<struct nl_client>::iterator it = tx_buff_list_.begin();
93  // Add all messages to to io-vector.
94  while (it != tx_buff_list_.end()) {
95  struct nl_client *cl = &(*it);
96  struct nlmsghdr *nlh = (struct nlmsghdr *)(cl->cl_buf);
97  // Set MULTI flag by default. It will be reset for last buffer later
98  nlh->nlmsg_flags |= NLM_F_MULTI;
99  last_nlh = nlh;
100  iovec.push_back(buffer(cl->cl_buf, cl->cl_msg_len));
101  it++;
102  count++;
103  }
104 
105  // If there are more than one NETLINK messages, we need to add
106  struct nlmsghdr nlh;
107  if (count > 1) {
108  //Send Netlink-Done message NLMSG_DONE at end
109  InitNetlinkDoneMsg(&nlh, last_nlh->nlmsg_seq);
110  iovec.push_back(buffer((uint8_t *)&nlh, NLMSG_HDRLEN));
111  } else {
112  // Single buffer. Reset the MULTI flag
113  if (last_nlh)
114  last_nlh->nlmsg_flags &= (~NLM_F_MULTI);
115  }
116 
117  // Send a message for each entry in io-vector
118  KSyncBufferList::iterator iovec_it = iovec.begin();
119  while (iovec_it != iovec.end()) {
120  sock_.send_to(*iovec_it, local_ep_);
121  iovec_it++;
122  }
123 
124  // Free the buffers
125  it = tx_buff_list_.begin();
126  while (it != tx_buff_list_.end()) {
127  struct nl_client *cl = &(*it);
128  nl_free(cl);
129  *it++;
130  }
131  tx_buff_list_.clear();
132 }
133 
134 void KSyncSockTypeMap::FlowNatResponse(uint32_t seq_num, vr_flow_req *req , int code) {
137  struct nl_client cl;
138  int error = 0, ret;
139  uint8_t *buf = NULL;
140  uint32_t buf_len = 0, encode_len = 0;
141  struct nlmsghdr *nlh;
142 
143  nl_init_generic_client_req(&cl, KSyncSock::GetNetlinkFamilyId());
144  if ((ret = nl_build_header(&cl, &buf, &buf_len)) < 0) {
145  LOG(DEBUG, "Error creating interface DUMP message : " << ret);
146  nl_free(&cl);
147  return;
148  }
149 
150  nlh = (struct nlmsghdr *)cl.cl_buf;
151  nlh->nlmsg_seq = seq_num;
152 
153  uint32_t fwd_flow_idx = req->get_fr_index();
154  bool add_error = false;
155  if (fwd_flow_idx == 0xFFFFFFFF) {
156  add_error = true;
157  } else {
158  if (flow_error != -ENOSPC && flow_error != 0) {
159  add_error = true;
160  }
161  if (code != 0) {
162  flow_error = code;
163  add_error = true;
164  }
165  }
166  if (add_error) {
167  encode_len = EncodeVrResponse(buf, buf_len, seq_num, flow_error);
168  } else {
169  encode_len = EncodeVrResponse(buf, buf_len, seq_num, 0);
170  }
171 
172  buf += encode_len;
173  buf_len -= encode_len;
174 
175  vr_flow_response resp;
176  resp.set_fresp_op(flow_op::FLOW_SET);
177  resp.set_fresp_flags(req->get_fr_flags());
178  resp.set_fresp_index(req->get_fr_index());
179  resp.set_fresp_gen_id(req->get_fr_gen_id());
180  resp.set_fresp_bytes(0);
181  resp.set_fresp_packets(0);
182  resp.set_fresp_stats_oflow(0);
183 
184  encode_len += resp.WriteBinary(buf, buf_len, &error);
185  if (error != 0) {
186  SimulateResponse(seq_num, -ENOENT, 0);
187  nl_free(&cl);
188  return;
189  }
190 
191  nl_update_header(&cl, encode_len);
192  sock->AddNetlinkTxBuff(&cl);
193 }
194 
195 void KSyncSockTypeMap::InitNetlinkDoneMsg(struct nlmsghdr *nlh,
196  uint32_t seq_num) {
197  nlh->nlmsg_seq = seq_num;
198  nlh->nlmsg_type = NLMSG_DONE;
199  nlh->nlmsg_len = NLMSG_HDRLEN;
200  nlh->nlmsg_flags = 0;
201 }
202 
203 void KSyncSockTypeMap::SimulateResponse(uint32_t seq_num, int code, int flags) {
204  struct nl_client cl;
205  int encode_len, ret;
206  uint8_t *buf;
207  uint32_t buf_len;
208 
209  nl_init_generic_client_req(&cl, KSyncSock::GetNetlinkFamilyId());
210  if ((ret = nl_build_header(&cl, &buf, &buf_len)) < 0) {
211  LOG(DEBUG, "Error creating mpls message. Error : " << ret);
212  nl_free(&cl);
213  return;
214  }
215 
216  struct nlmsghdr *nlh = (struct nlmsghdr *)cl.cl_buf;
217  nlh->nlmsg_seq = seq_num;
218  nlh->nlmsg_flags |= flags;
219  encode_len = EncodeVrResponse(buf, buf_len, seq_num, code);
220  nl_update_header(&cl, encode_len);
221  LOG(DEBUG, "SimulateResponse " << " seq " << seq_num << " code " << std::hex << code);
222 
224  sock->AddNetlinkTxBuff(&cl);
225 }
226 
228  for(int i = 0; i < IoContext::MAX_WORK_QUEUES; i++) {
229  ksync_rx_queue[i]->set_disable(disable);
230  }
231 }
232 
233 void KSyncSockTypeMap::SetDropStats(const vr_drop_stats_req &req) {
235  sock->drop_stats = req;
236 }
237 
238 void KSyncSockTypeMap::SetVRouterOps(const vrouter_ops &req) {
240  sock->ksync_vrouter_ops = req;
241 }
242 
243 void KSyncSockTypeMap::InterfaceAdd(int id, int flags, int mac_size) {
245  KSyncSockTypeMap::ksync_map_if::const_iterator it;
246  static int os_index = 10;
247  char name[50];
248  sprintf(name, "intf%d", id);
249  vr_interface_req req;
250  req.set_vifr_idx(id);
251  req.set_vifr_type(VIF_TYPE_VIRTUAL);
252  req.set_vifr_rid(0);
253  req.set_vifr_os_idx(os_index);
254  req.set_vifr_name(name);
255  const std::vector<signed char> list(mac_size);
256  req.set_vifr_mac(list);
257  req.set_vifr_flags(flags);
258 
259  it = sock->if_map.find(id);
260  if (it == sock->if_map.end()) {
261  sock->if_map[id] = req;
262  ++os_index;
263  }
264 }
265 
268  KSyncSockTypeMap::ksync_map_if::iterator it;
269  it = sock->if_map.find(id);
270  if (it != sock->if_map.end()) {
271  sock->if_map.erase(it);
272  }
273 }
274 
275 void KSyncSockTypeMap::NHAdd(int id, int flags) {
277  KSyncSockTypeMap::ksync_map_nh::const_iterator it;
278  vr_nexthop_req req;
279  req.set_nhr_id(id);
280  req.set_nhr_flags(flags);
281  it = sock->nh_map.find(id);
282  if (it == sock->nh_map.end()) {
283  sock->nh_map[id] = req;
284  }
285 }
286 
289  KSyncSockTypeMap::ksync_map_nh::iterator it;
290  it = sock->nh_map.find(id);
291  if (it != sock->nh_map.end()) {
292  sock->nh_map.erase(it);
293  }
294 }
295 
298  KSyncSockTypeMap::ksync_map_mpls::const_iterator it;
299  vr_mpls_req req;
300  req.set_mr_label(id);
301  it = sock->mpls_map.find(id);
302  if (it == sock->mpls_map.end()) {
303  sock->mpls_map[id] = req;
304  }
305 }
306 
309  KSyncSockTypeMap::ksync_map_mpls::iterator it;
310  it = sock->mpls_map.find(id);
311  if (it != sock->mpls_map.end()) {
312  sock->mpls_map.erase(it);
313  }
314 }
315 
318  KSyncSockTypeMap::ksync_map_mirror::const_iterator it;
319  vr_mirror_req req;
320  req.set_mirr_index(id);
321  it = sock->mirror_map.find(id);
322  if (it == sock->mirror_map.end()) {
323  sock->mirror_map[id] = req;
324  }
325 }
326 
329  KSyncSockTypeMap::ksync_map_mirror::iterator it;
330  it = sock->mirror_map.find(id);
331  if (it != sock->mirror_map.end()) {
332  sock->mirror_map.erase(it);
333  }
334 }
335 
336 void KSyncSockTypeMap::RouteAdd(vr_route_req &req) {
338  //store in the route tree
339  std::pair<std::set<vr_route_req>::iterator, bool> ret;
340  ret = sock->rt_tree.insert(req);
341 
342  /* If insertion fails, remove the existing entry and add the new one */
343  if (ret.second == false) {
344  int del_count = sock->rt_tree.erase(req);
345  assert(del_count);
346  ret = sock->rt_tree.insert(req);
347  assert(ret.second == true);
348  }
349  if (req.get_rtr_family() == AF_BRIDGE) {
350  sock->SetBridgeEntry((uint32_t)req.get_rtr_index(), &req, true);
351  }
352 }
353 
354 void KSyncSockTypeMap::RouteDelete(vr_route_req &req) {
356  KSyncSockTypeMap::ksync_rt_tree::iterator it;
357  it = sock->rt_tree.find(req);
358  if (it != sock->rt_tree.end()) {
359  sock->rt_tree.erase(it);
360  }
361 }
362 
363 void KSyncSockTypeMap::VrfAssignAdd(vr_vrf_assign_req &req) {
365  KSyncSockTypeMap::ksync_vrf_assign_tree::const_iterator it;
366  it = sock->vrf_assign_tree.find(req);
367  if (it == sock->vrf_assign_tree.end()) {
368  sock->vrf_assign_tree.insert(req);
369  }
370 }
371 
372 void KSyncSockTypeMap::VrfAssignDelete(vr_vrf_assign_req &req) {
374  KSyncSockTypeMap::ksync_vrf_assign_tree::iterator it;
375  it = sock->vrf_assign_tree.find(req);
376  if (it != sock->vrf_assign_tree.end()) {
377  sock->vrf_assign_tree.erase(it);
378  }
379 }
380 
383  KSyncSockTypeMap::ksync_map_vrf_stats::const_iterator it;
384  vr_vrf_stats_req vrf_stats;
385  vrf_stats.set_vsr_vrf(vrf_id);
386  vrf_stats.set_vsr_family(AF_INET);
387  vrf_stats.set_vsr_rid(0);
388  vrf_stats.set_vsr_discards(0);
389  vrf_stats.set_vsr_resolves(0);
390  vrf_stats.set_vsr_receives(0);
391  vrf_stats.set_vsr_udp_tunnels(0);
392  vrf_stats.set_vsr_udp_mpls_tunnels(0);
393  vrf_stats.set_vsr_gre_mpls_tunnels(0);
394  vrf_stats.set_vsr_ecmp_composites(0);
395  vrf_stats.set_vsr_fabric_composites(0);
396  vrf_stats.set_vsr_l2_mcast_composites(0);
397  vrf_stats.set_vsr_encaps(0);
398  vrf_stats.set_vsr_l2_encaps(0);
399 
400  it = sock->vrf_stats_map.find(vrf_id);
401  if (it == sock->vrf_stats_map.end()) {
402  sock->vrf_stats_map[vrf_id] = vrf_stats;
403  }
404 }
405 
408  KSyncSockTypeMap::ksync_map_vrf_stats::iterator it;
409  it = sock->vrf_stats_map.find(vrf_id);
410  if (it != sock->vrf_stats_map.end()) {
411  sock->vrf_stats_map.erase(it);
412  }
413 }
414 
415 void KSyncSockTypeMap::VrfStatsUpdate(int vrf_id, const vr_vrf_stats_req &req) {
417  vr_vrf_stats_req &r = sock->vrf_stats_map[vrf_id];
418  r.set_vsr_discards(req.get_vsr_discards());
419  r.set_vsr_resolves(req.get_vsr_resolves());
420  r.set_vsr_receives(req.get_vsr_receives());
421  r.set_vsr_udp_tunnels(req.get_vsr_udp_tunnels());
422  r.set_vsr_udp_mpls_tunnels(req.get_vsr_udp_mpls_tunnels());
423  r.set_vsr_gre_mpls_tunnels(req.get_vsr_gre_mpls_tunnels());
424  r.set_vsr_ecmp_composites(req.get_vsr_ecmp_composites());
425  r.set_vsr_l2_mcast_composites(req.get_vsr_l2_mcast_composites());
426  r.set_vsr_fabric_composites(req.get_vsr_fabric_composites());
427  r.set_vsr_encaps(req.get_vsr_encaps());
428  r.set_vsr_l2_encaps(req.get_vsr_l2_encaps());
429  r.set_vsr_gros(req.get_vsr_gros());
430  r.set_vsr_diags(req.get_vsr_diags());
431  r.set_vsr_encap_composites(req.get_vsr_encap_composites());
432  r.set_vsr_evpn_composites(req.get_vsr_evpn_composites());
433  r.set_vsr_vrf_translates(req.get_vsr_vrf_translates());
434  r.set_vsr_vxlan_tunnels(req.get_vsr_vxlan_tunnels());
435  r.set_vsr_arp_virtual_proxy(req.get_vsr_arp_virtual_proxy());
436  r.set_vsr_arp_virtual_stitch(req.get_vsr_arp_virtual_stitch());
437  r.set_vsr_arp_virtual_flood(req.get_vsr_arp_virtual_flood());
438  r.set_vsr_arp_physical_stitch(req.get_vsr_arp_physical_stitch());
439  r.set_vsr_arp_tor_proxy(req.get_vsr_arp_tor_proxy());
440  r.set_vsr_arp_physical_flood(req.get_vsr_arp_physical_flood());
441  r.set_vsr_l2_receives(req.get_vsr_l2_receives());
442  r.set_vsr_uuc_floods(req.get_vsr_uuc_floods());
443 }
444 
447  KSyncSockTypeMap::ksync_map_vxlan::const_iterator it;
448 
449  it = sock->vxlan_map.find(id);
450  if (it == sock->vxlan_map.end()) {
451  vr_vxlan_req vxlan;
452  vxlan.set_vxlanr_vnid(id);
453  vxlan.set_vxlanr_rid(0);
454  sock->vxlan_map[id] = vxlan;
455  }
456 }
457 
460  KSyncSockTypeMap::ksync_map_vxlan::iterator it;
461 
462  it = sock->vxlan_map.find(id);
463  if (it != sock->vxlan_map.end()) {
464  sock->vxlan_map.erase(it);
465  }
466 }
467 
468 void KSyncSockTypeMap::IfStatsUpdate(int idx, int ibytes, int ipkts, int ierrors,
469  int obytes, int opkts, int oerrors) {
471  vr_interface_req req = sock->if_map[idx];
472  req.set_vifr_ibytes(ibytes+req.get_vifr_ibytes());
473  req.set_vifr_ipackets(ipkts+req.get_vifr_ipackets());
474  req.set_vifr_ierrors(ierrors+req.get_vifr_ierrors());
475  req.set_vifr_obytes(obytes+req.get_vifr_obytes());
476  req.set_vifr_opackets(opkts+req.get_vifr_opackets());
477  req.set_vifr_oerrors(oerrors+req.get_vifr_oerrors());
478  sock->if_map[idx] = req;
479 }
480 
481 void KSyncSockTypeMap::IfStatsSet(int idx, int ibytes, int ipkts, int ierrors,
482  int obytes, int opkts, int oerrors) {
484  vr_interface_req req = sock->if_map[idx];
485  req.set_vifr_ibytes(ibytes);
486  req.set_vifr_ipackets(ipkts);
487  req.set_vifr_ierrors(ierrors);
488  req.set_vifr_obytes(obytes);
489  req.set_vifr_opackets(opkts);
490  req.set_vifr_oerrors(oerrors);
491  sock->if_map[idx] = req;
492 }
493 
496  return sock->if_map.size();
497 }
498 
501  return sock->nh_map.size();
502 }
503 
506  return sock->mpls_map.size();
507 }
508 
511  return sock->rt_tree.size();
512 }
513 
516  return sock->vxlan_map.size();
517 }
518 
519 uint32_t KSyncSockTypeMap::GetSeqno(char *data) {
520  struct nlmsghdr *nlh = (struct nlmsghdr *)data;
521  return nlh->nlmsg_seq;
522 }
523 
525  struct nlmsghdr *nlh = (struct nlmsghdr *)data;
526 
527  return (nlh->nlmsg_flags & NLM_F_MULTI);
528 }
529 
531  KSyncBulkSandeshContext *bulk_context) {
532  KSyncSockNetlink::NetlinkBulkDecoder(data, bulk_context, IsMoreData(data));
533  return true;
534 }
535 
536 bool KSyncSockTypeMap::Decoder(char *data, AgentSandeshContext *context) {
537  KSyncSockNetlink::NetlinkDecoder(data, context);
538  return true;
539 }
540 
541 bool KSyncSockTypeMap::Validate(char *data) {
542  struct nlmsghdr *nlh = (struct nlmsghdr *)data;
543  if (nlh->nlmsg_type == NLMSG_ERROR) {
544  LOG(ERROR, "Ignoring Netlink error for seqno " << nlh->nlmsg_seq
545  << " len " << nlh->nlmsg_len);
546  assert(0);
547  return true;
548  }
549 
550  if (nlh->nlmsg_len > kBufLen) {
551  LOG(ERROR, "Length of " << nlh->nlmsg_len << " is more than expected "
552  "length of " << kBufLen);
553  assert(0);
554  return true;
555  }
556  return true;
557 }
558 
559 static void IoVectorToData(std::string& data, KSyncBufferList *iovec) {
560  KSyncBufferList::iterator it = iovec->begin();
561  while (it != iovec->end()) {
562  unsigned char *buf = boost::asio::buffer_cast<unsigned char *>(*it);
563  int buffer_size = boost::asio::buffer_size(*it);
564  data.append(reinterpret_cast<const char*>(buf), buffer_size);
565  it++;
566  }
567 }
568 
569 //send or store in map
570 void KSyncSockTypeMap::AsyncSendTo(KSyncBufferList *iovec, uint32_t seq_no,
571  HandlerCb cb) {
572  std::string data = "";
573  IoVectorToData(data, iovec);
574 
575  KSyncUserSockContext ctx(seq_no);
576  //parse and store info in map [done in Process() callbacks]
577  ProcessSandesh((const uint8_t *)(data.c_str()), data.size(), &ctx);
578 }
579 
580 //send or store in map
581 std::size_t KSyncSockTypeMap::SendTo(KSyncBufferList *iovec, uint32_t seq_no) {
582  std::string data = "";
583  IoVectorToData(data, iovec);
584 
585  KSyncUserSockContext ctx(seq_no);
586  //parse and store info in map [done in Process() callbacks]
587  ProcessSandesh((const uint8_t *)(data.c_str()), data.size(), &ctx);
588  return 0;
589 }
590 
591 //receive msgs from datapath
592 void KSyncSockTypeMap::AsyncReceive(mutable_buffers_1 buf, HandlerCb cb) {
593  sock_.async_receive_from(buf, local_ep_, cb);
594 }
595 
596 //receive msgs from datapath
597 void KSyncSockTypeMap::Receive(mutable_buffers_1 buf) {
598  sock_.receive(buf);
599 }
600 
601 vr_flow_entry *KSyncSockTypeMap::FlowMmapAlloc(int size) {
602  flow_table_ = (vr_flow_entry *)malloc(size);
603  return flow_table_;
604 }
605 
607  if (flow_table_) {
608  free(flow_table_);
609  flow_table_ = NULL;
610  }
611 }
612 
613 vr_flow_entry *KSyncSockTypeMap::GetFlowEntry(int idx) {
614  return &flow_table_[idx];
615 }
616 
617 void KSyncSockTypeMap::SetFlowEntry(vr_flow_req *req, bool set) {
618  uint32_t idx = req->get_fr_index();
619 
620  vr_flow_entry *f = &flow_table_[idx];
621  if (!set) {
622  f->fe_flags &= ~VR_FLOW_FLAG_ACTIVE;
623  f->fe_stats.flow_bytes = 0;
624  f->fe_stats.flow_packets = 0;
625  f->fe_gen_id = 0;
626  return;
627  }
628 
629  int family = (req->get_fr_family() == AF_INET)? Address::INET :
631  IpAddress sip;
632  IpAddress dip;
633  U64ToIp(req->get_fr_flow_sip_u(), req->get_fr_flow_sip_l(),
634  req->get_fr_flow_dip_u(), req->get_fr_flow_dip_l(),
635  family, &sip, &dip);
636  f->fe_flags = VR_FLOW_FLAG_ACTIVE;
637  f->fe_stats.flow_bytes = 30;
638  f->fe_stats.flow_packets = 1;
639  f->fe_gen_id = req->get_fr_gen_id();
640  if (sip.is_v4()) {
641  f->fe_key.flow4_sip = htonl(sip.to_v4().to_ulong());
642  f->fe_key.flow4_dip = htonl(dip.to_v4().to_ulong());
643  }
644  if (family == Address::INET) {
645  f->fe_key.flow4_nh_id = req->get_fr_flow_nh_id();
646  } else {
647  f->fe_key.flow6_nh_id = req->get_fr_flow_nh_id();
648  }
649  f->fe_key.flow_family = req->get_fr_family();
650  f->fe_key.flow_sport = req->get_fr_flow_sport();
651  f->fe_key.flow_dport = req->get_fr_flow_dport();
652  f->fe_key.flow_nh_id = req->get_fr_flow_nh_id();
653  f->fe_key.flow_proto = req->get_fr_flow_proto();
654 }
655 
657  vr_flow_entry *f = &flow_table_[idx];
658  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
659  f->fe_flags |= VR_FLOW_FLAG_EVICTED;
660  }
661 }
662 
664  vr_flow_entry *f = &flow_table_[idx];
665  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
666  f->fe_flags &= ~VR_FLOW_FLAG_EVICTED;
667  }
668 }
669 
670 
671 void KSyncSockTypeMap::IncrFlowStats(int idx, int pkts, int bytes) {
672  vr_flow_entry *f = &flow_table_[idx];
673  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
674  f->fe_stats.flow_bytes += bytes;
675  f->fe_stats.flow_packets += pkts;
676  }
677 }
678 
679 void KSyncSockTypeMap::SetTcpFlag(int idx, uint32_t flags) {
680  vr_flow_entry *f = &flow_table_[idx];
681  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
682  f->fe_tcp_flags = flags;
683  }
684 }
685 
686 void KSyncSockTypeMap::SetFlowTcpFlags(int idx, uint16_t flags) {
687  vr_flow_entry *f = &flow_table_[idx];
688  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
689  f->fe_tcp_flags = flags;
690  }
691 }
692 
694  vr_flow_entry *f = &flow_table_[idx];
695  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
696  f->fe_udp_src_port = port;
697  }
698 }
699 
700 void KSyncSockTypeMap::SetOFlowStats(int idx, uint8_t pkts, uint16_t bytes) {
701  vr_flow_entry *f = &flow_table_[idx];
702  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
703  f->fe_stats.flow_bytes_oflow = bytes;
704  f->fe_stats.flow_packets_oflow = pkts;
705  }
706 }
707 
708 vr_bridge_entry *KSyncSockTypeMap::BridgeMmapAlloc(int size) {
709  bridge_table_ = (vr_bridge_entry *)malloc(size);
710  memset(bridge_table_, 0, size);
711  return bridge_table_;
712 }
713 
715  if (bridge_table_) {
716  free(bridge_table_);
717  bridge_table_ = NULL;
718  }
719 }
720 
721 vr_bridge_entry *KSyncSockTypeMap::GetBridgeEntry(int idx) {
722  return &bridge_table_[idx];
723 }
724 
725 void KSyncSockTypeMap::SetBridgeEntry(uint32_t idx, vr_route_req *req,
726  bool set) {
727  vr_bridge_entry *be = &bridge_table_[idx];
728  if (!set) {
729  be->be_packets = 0;
730  return;
731  }
732 
733  if (be->be_packets == 0) {
734  be->be_packets = 1;
735  }
736  vr_bridge_entry_key *key = &be->be_key;
737 
738  //Copy VRF and mac
739  key->be_vrf_id = req->get_rtr_vrf_id();
740 
741  uint8_t i = 0;
742  const std::vector<signed char> &prefix = req->get_rtr_mac();
743  for(std::vector<signed char>::const_iterator it = prefix.begin();
744  it != prefix.end(); ++it) {
745  key->be_mac[i] = ((uint8_t) *it);
746  i++;
747  }
748 }
749 
751  vr_bridge_entry *be = &bridge_table_[idx];
752  if (set) {
753  be->be_flags |= VR_BE_MAC_NEW_FLAG;
754  } else {
755  be->be_flags &= ~VR_BE_MAC_NEW_FLAG;
756  }
757 }
758 
759 //init ksync map
760 void KSyncSockTypeMap::Init(boost::asio::io_context &ios) {
761  assert(singleton_ == NULL);
762 
763  singleton_ = new KSyncSockTypeMap(ios);
764  KSyncSock::SetSockTableEntry(singleton_);
765  KSyncSock::Init(true, "disabled");
766 
767  singleton_->local_ep_.address
768  (boost::asio::ip::address::from_string("127.0.0.1"));
769  singleton_->local_ep_.port(0);
770  singleton_->sock_.open(boost::asio::ip::udp::v4());
771  singleton_->sock_.bind(singleton_->local_ep_);
772  singleton_->local_ep_ = singleton_->sock_.local_endpoint();
773 }
774 
776  delete singleton_;
777  singleton_ = NULL;
778 }
779 
781  while (!ctx_queue_.empty()) {
782  ctx_queue_.front()->Process();
783  delete ctx_queue_.front();
784  ctx_queue_.pop();
785  }
786  PurgeTxBuffer();
787 }
788 
790  tbb::mutex::scoped_lock lock(ctx_queue_lock_);
791  if (block_msg_processing_ != enable) {
792  block_msg_processing_ = enable;
793  if (!block_msg_processing_) {
794  PurgeBlockedMsg();
795  }
796  }
797 }
798 
801 
802  //delete from map if command is delete
803  if (req_->get_h_op() == sandesh_op::DEL) {
804  sock->if_map.erase(req_->get_vifr_idx());
805  } else if (req_->get_h_op() == sandesh_op::DUMP) {
806  IfDumpHandler dump;
807  dump.SendDumpResponse(GetSeqNum(), req_);
808  return;
809  } else if (req_->get_h_op() == sandesh_op::GET) {
810  IfDumpHandler dump;
811  dump.SendGetResponse(GetSeqNum(), req_->get_vifr_idx());
812  return;
813  } else {
814  //store in the map
815  vr_interface_req if_info(*req_);
816  sock->if_map[req_->get_vifr_idx()] = if_info;
817  }
818  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
819 }
820 
821 void KSyncUserSockContext::IfMsgHandler(vr_interface_req *req) {
823  KSyncUserSockIfContext *ifctx = new KSyncUserSockIfContext(GetSeqNum(), req);
824 
825  if (sock->IsBlockMsgProcessing()) {
826  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
827  sock->ctx_queue_.push(ifctx);
828  } else {
829  ifctx->Process();
830  delete ifctx;
831  }
832 }
833 
836  uint16_t flags = 0;
838 
839  flags = req_->get_fr_flags();
840  //delete from map if command is delete
841  if (!flags) {
842  sock->flow_map.erase(req_->get_fr_index());
843  //Deactivate the flow-entry in flow mmap
844  KSyncSockTypeMap::SetFlowEntry(req_, false);
845  } else {
846  uint32_t fwd_flow_idx = req_->get_fr_index();
847  if (fwd_flow_idx == 0xFFFFFFFF) {
848  if (flow_error == 0) {
849  /* Allocate entry only of no error case */
850  if (sock->is_incremental_index()) {
851  /* Send reverse-flow index as one more than fwd-flow index */
852  fwd_flow_idx = req_->get_fr_rindex() + 1;
853  } else {
854  fwd_flow_idx = rand() % 20000;
855  /* Reserve first 20000 indexes for forwarding flow
856  * Reverse flow indexes will start from 20000 always
857  */
858  fwd_flow_idx += 20000;
859  }
860  /* If the randomly allocated index is used already then
861  * find out the next randon index which is free
862  */
863  if (sock->is_incremental_index()) {
864  if (sock->flow_map.find(fwd_flow_idx) != sock->flow_map.end()) {
865  //sock->SimulateResponse(GetSeqNum(), -EEXIST, 0);
866  int code = -EEXIST;
867  req_->set_fr_index(fwd_flow_idx);
868  req_->set_fr_gen_id((fwd_flow_idx % 255));
869  KSyncSockTypeMap::FlowNatResponse(GetSeqNum(), req_, code);
870  return;
871  }
872  } else {
873  while (sock->flow_map.find(fwd_flow_idx) != sock->flow_map.end()) {
874  fwd_flow_idx = rand() % 20000;
875  /* Reserve first 20000 indexes for forwarding flow
876  * Reverse flow indexes will start from 20000 always
877  */
878  fwd_flow_idx += 20000;
879  }
880  }
881  req_->set_fr_index(fwd_flow_idx);
882  req_->set_fr_gen_id((fwd_flow_idx % 255));
883  }
884  }
885 
886  if (fwd_flow_idx != 0xFFFFFFFF) {
887  //store info from binary sandesh message
888  vr_flow_req flow_info(*req_);
889 
890  sock->flow_map[req_->get_fr_index()] = flow_info;
891 
892  //Activate the flow-entry in flow mmap
893  KSyncSockTypeMap::SetFlowEntry(req_, true);
894  }
895 
896  // For NAT flow, don't send vr_response, instead send
897  // vr_flow_req with index of reverse_flow
898  KSyncSockTypeMap::FlowNatResponse(GetSeqNum(), req_);
899  return;
900  }
901  KSyncSockTypeMap::FlowNatResponse(GetSeqNum(), req_);
902 }
903 
904 void KSyncUserSockContext::FlowMsgHandler(vr_flow_req *req) {
906  KSyncUserSockFlowContext *flowctx = new KSyncUserSockFlowContext(GetSeqNum(), req);
907 
908  if (sock->IsBlockMsgProcessing()) {
909  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
910  sock->ctx_queue_.push(flowctx);
911  } else {
912  flowctx->Process();
913  delete flowctx;
914  }
915 }
916 
919 
920  //delete from map if command is delete
921  if (req_->get_h_op() == sandesh_op::DEL) {
922  sock->nh_map.erase(req_->get_nhr_id());
923  } else if (req_->get_h_op() == sandesh_op::DUMP) {
924  NHDumpHandler dump;
925  dump.SendDumpResponse(GetSeqNum(), req_);
926  return;
927  } else if (req_->get_h_op() == sandesh_op::GET) {
928  NHDumpHandler dump;
929  dump.SendGetResponse(GetSeqNum(), req_->get_nhr_id());
930  return;
931  } else {
932  //store in the map
933  vr_nexthop_req nh_info(*req_);
934  sock->nh_map[req_->get_nhr_id()] = nh_info;
935  }
936  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
937 }
938 
939 void KSyncUserSockContext::NHMsgHandler(vr_nexthop_req *req) {
941  KSyncUserSockNHContext *nhctx = new KSyncUserSockNHContext(GetSeqNum(), req);
942 
943  if (sock->IsBlockMsgProcessing()) {
944  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
945  sock->ctx_queue_.push(nhctx);
946  } else {
947  nhctx->Process();
948  delete nhctx;
949  }
950 }
951 
954 
955  //delete from map mpls command is delete
956  if (req_->get_h_op() == sandesh_op::DEL) {
957  sock->mpls_map.erase(req_->get_mr_label());
958  } else if (req_->get_h_op() == sandesh_op::DUMP) {
959  MplsDumpHandler dump;
960  dump.SendDumpResponse(GetSeqNum(), req_);
961  return;
962  } else if (req_->get_h_op() == sandesh_op::GET) {
963  MplsDumpHandler dump;
964  dump.SendGetResponse(GetSeqNum(), req_->get_mr_label());
965  return;
966  } else {
967  //store in the map
968  vr_mpls_req mpls_info(*req_);
969  sock->mpls_map[req_->get_mr_label()] = mpls_info;
970  }
971  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
972 }
973 
974 void KSyncUserSockContext::MplsMsgHandler(vr_mpls_req *req) {
976  KSyncUserSockMplsContext *mplsctx = new KSyncUserSockMplsContext(GetSeqNum(), req);
977 
978  if (sock->IsBlockMsgProcessing()) {
979  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
980  sock->ctx_queue_.push(mplsctx);
981  } else {
982  mplsctx->Process();
983  delete mplsctx;
984  }
985 }
986 
989 
990  //delete from the route tree, if the command is delete
991  if (req_->get_h_op() == sandesh_op::DEL) {
992  if (req_->get_rtr_family() == AF_BRIDGE) {
993  sock->UpdateBridgeEntryInactiveFlag(req_->get_rtr_index(), false);
994  }
995  sock->rt_tree.erase(*req_);
996  } else if (req_->get_h_op() == sandesh_op::DUMP) {
997  RouteDumpHandler dump;
998  sock->SetBridgeEntry(req_->get_rtr_index(), req_, false);
999  dump.SendDumpResponse(GetSeqNum(), req_);
1000  return;
1001  } else {
1002  sock->RouteAdd(*req_);
1003  }
1004  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1005 }
1006 
1007 void KSyncUserSockContext::RouteMsgHandler(vr_route_req *req) {
1009  KSyncUserSockRouteContext *rtctx = new KSyncUserSockRouteContext(GetSeqNum(), req);
1010 
1011  if (sock->IsBlockMsgProcessing()) {
1012  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1013  sock->ctx_queue_.push(rtctx);
1014  } else {
1015  rtctx->Process();
1016  delete rtctx;
1017  }
1018 }
1019 
1021  assert(0);
1022 }
1023 
1025  assert(0);
1026 }
1027 
1028 void KSyncUserSockContext::MirrorMsgHandler(vr_mirror_req *req) {
1030 
1031  //delete from map if command is delete
1032  if (req->get_h_op() == sandesh_op::DEL) {
1033  sock->mirror_map.erase(req->get_mirr_index());
1034  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1035  return;
1036  }
1037 
1038  if (req->get_h_op() == sandesh_op::DUMP) {
1039  MirrorDumpHandler dump;
1040  dump.SendDumpResponse(GetSeqNum(), req);
1041  return;
1042  }
1043 
1044  if (req->get_h_op() == sandesh_op::GET) {
1045  MirrorDumpHandler dump;
1046  dump.SendGetResponse(GetSeqNum(), req->get_mirr_index());
1047  return;
1048  }
1049 
1050  //store in the map
1051  vr_mirror_req mirror_info(*req);
1052  sock->mirror_map[req->get_mirr_index()] = mirror_info;
1053  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1054 }
1055 
1058 
1059  //delete from map vxlan command is delete
1060  if (req_->get_h_op() == sandesh_op::DEL) {
1061  sock->vxlan_map.erase(req_->get_vxlanr_vnid());
1062  } else if (req_->get_h_op() == sandesh_op::DUMP) {
1063  VxLanDumpHandler dump;
1064  dump.SendDumpResponse(GetSeqNum(), req_);
1065  return;
1066  } else if (req_->get_h_op() == sandesh_op::GET) {
1067  VxLanDumpHandler dump;
1068  dump.SendGetResponse(GetSeqNum(), req_->get_vxlanr_vnid());
1069  return;
1070  } else {
1071  //store in the map
1072  vr_vxlan_req vxlan_info(*req_);
1073  sock->vxlan_map[req_->get_vxlanr_vnid()] = vxlan_info;
1074  }
1075  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1076 }
1077 
1078 void KSyncUserSockContext::VxLanMsgHandler(vr_vxlan_req *req) {
1080  KSyncUserSockVxLanContext *vxlanctx =
1081  new KSyncUserSockVxLanContext(GetSeqNum(), req);
1082 
1083  if (sock->IsBlockMsgProcessing()) {
1084  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1085  sock->ctx_queue_.push(vxlanctx);
1086  } else {
1087  vxlanctx->Process();
1088  delete vxlanctx;
1089  }
1090 }
1091 
1092 
1095  if (req_->get_h_op() == sandesh_op::GET) {
1096  VRouterOpsDumpHandler dump;
1097  sock->ksync_vrouter_ops.set_vo_mpls_labels(10000);
1098  dump.SendGetResponse(GetSeqNum(), 0);
1099  return;
1100  }
1101 }
1104  KSyncUserVrouterOpsContext *vrouter_ops =
1105  new KSyncUserVrouterOpsContext(GetSeqNum(), req);
1106 
1107  if (sock->IsBlockMsgProcessing()) {
1108  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1109  sock->ctx_queue_.push(vrouter_ops);
1110  } else {
1111  vrouter_ops->Process();
1112  delete vrouter_ops;
1113  }
1114 }
1115 
1118 
1119  //delete from the vrf assign tree, if the command is delete
1120  if (req_->get_h_op() == sandesh_op::DEL) {
1121  sock->vrf_assign_tree.erase(*req_);
1122  } else if (req_->get_h_op() == sandesh_op::DUMP) {
1123  VrfAssignDumpHandler dump;
1124  dump.SendDumpResponse(GetSeqNum(), req_);
1125  return;
1126  } else {
1127  //store in the vrf assign tree
1128  std::pair<std::set<vr_vrf_assign_req>::iterator, bool> ret;
1129  ret = sock->vrf_assign_tree.insert(*req_);
1130 
1131  /* If insertion fails, remove the existing entry and add the new one */
1132  if (ret.second == false) {
1133  int del_count = sock->vrf_assign_tree.erase(*req_);
1134  assert(del_count);
1135  ret = sock->vrf_assign_tree.insert(*req_);
1136  assert(ret.second == true);
1137  }
1138  }
1139  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1140 }
1141 
1142 void KSyncUserSockContext::VrfAssignMsgHandler(vr_vrf_assign_req *req) {
1145  new KSyncUserSockVrfAssignContext(GetSeqNum(), req);
1146 
1147  if (sock->IsBlockMsgProcessing()) {
1148  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1149  sock->ctx_queue_.push(ctx);
1150  } else {
1151  ctx->Process();
1152  delete ctx;
1153  }
1154 }
1155 
1158 
1159  //delete from map if command is delete
1160  if (req_->get_h_op() == sandesh_op::DEL) {
1161  sock->vrf_map.erase(req_->get_vrf_idx());
1162  } else if (req_->get_h_op() == sandesh_op::DUMP) {
1163  VrfDumpHandler dump;
1164  dump.SendDumpResponse(GetSeqNum(), req_);
1165  return;
1166  } else if (req_->get_h_op() == sandesh_op::GET) {
1167  VrfDumpHandler dump;
1168  dump.SendGetResponse(GetSeqNum(), req_->get_vrf_idx());
1169  return;
1170  } else {
1171  //store in the map
1172  vr_vrf_req vrf_info(*req_);
1173  sock->vrf_map[req_->get_vrf_idx()] = vrf_info;
1174  }
1175  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1176 }
1180  new KSyncUserSockVrfContext(GetSeqNum(), req);
1181 
1182  if (sock->IsBlockMsgProcessing()) {
1183  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1184  sock->ctx_queue_.push(ctx);
1185  } else {
1186  ctx->Process();
1187  delete ctx;
1188  }
1189 }
1190 
1192  if (req_->get_h_op() == sandesh_op::DUMP) {
1193  VrfStatsDumpHandler dump;
1194  dump.SendDumpResponse(GetSeqNum(), req_);
1195  } else if (req_->get_h_op() == sandesh_op::GET) {
1196  VrfStatsDumpHandler dump;
1197  dump.SendGetResponse(GetSeqNum(), req_->get_vsr_vrf());
1198  }
1199 }
1200 
1201 void KSyncUserSockContext::VrfStatsMsgHandler(vr_vrf_stats_req *req) {
1204  GetSeqNum(), req);
1205 
1206  if (sock->IsBlockMsgProcessing()) {
1207  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1208  sock->ctx_queue_.push(vrfctx);
1209  } else {
1210  vrfctx->Process();
1211  delete vrfctx;
1212  }
1213 }
1214 
1216  if (req_->get_h_op() == sandesh_op::GET) {
1217  DropStatsDumpHandler dump;
1218  dump.SendGetResponse(GetSeqNum(), 0);
1219  }
1220 }
1221 
1222 void KSyncUserSockContext::DropStatsMsgHandler(vr_drop_stats_req *req) {
1225  GetSeqNum(), req);
1226 
1227  if (sock->IsBlockMsgProcessing()) {
1228  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1229  sock->ctx_queue_.push(dropctx);
1230  } else {
1231  dropctx->Process();
1232  delete dropctx;
1233  }
1234 }
1235 
1236 void MockDumpHandlerBase::SendDumpResponse(uint32_t seq_num, Sandesh *from_req) {
1238  struct nl_client cl;
1239  int error = 0, ret;
1240  uint8_t *buf = NULL;
1241  uint32_t buf_len = 0, encode_len = 0, tot_encode_len = 0;
1242  struct nlmsghdr *nlh = NULL;
1243  bool more = false;
1244  int count = 0;
1245  unsigned int resp_code = 0;
1246 
1248  int ret_code = -KSyncSockTypeMap::error_code();
1249  ret_code &= ~VR_MESSAGE_DUMP_INCOMPLETE;
1250  KSyncSockTypeMap::SimulateResponse(seq_num, ret_code, 0);
1251  return;
1252  }
1253  Sandesh *req = GetFirst(from_req);
1254  if (req != NULL) {
1255  nl_init_generic_client_req(&cl, KSyncSock::GetNetlinkFamilyId());
1256  if ((ret = nl_build_header(&cl, &buf, &buf_len)) < 0) {
1257  LOG(DEBUG, "Error creating interface DUMP message : " << ret);
1258  nl_free(&cl);
1259  return;
1260  }
1261 
1262  nlh = (struct nlmsghdr *)cl.cl_buf;
1263  nlh->nlmsg_seq = seq_num;
1264  }
1265 
1266  while(req != NULL) {
1267  encode_len = req->WriteBinary(buf, buf_len, &error);
1268  if (error != 0) {
1269  break;
1270  }
1271  buf += encode_len;
1272  buf_len -= encode_len;
1273  tot_encode_len += encode_len;
1274  count++;
1275 
1276  req = GetNext(req);
1277  //If the remaining buffer length cannot accomodate any more encoded
1278  //messages, quit from the loop.
1279  if (req != NULL && buf_len < encode_len) {
1280  more = true;
1281  break;
1282  }
1283  }
1284 
1285  if (error) {
1286  KSyncSockTypeMap::SimulateResponse(seq_num, -ENOENT, 0);
1287  nl_free(&cl);
1288  return;
1289  }
1290 
1291  resp_code = count;
1292  if (count > 0) {
1293  resp_code = count;
1294  if (more) {
1295  resp_code = resp_code | VR_MESSAGE_DUMP_INCOMPLETE;
1296  }
1297  //Send Vr-Response (with multi-flag set)
1298  KSyncSockTypeMap::SimulateResponse(seq_num, resp_code, NLM_F_MULTI);
1299 
1300  //Send dump-response containing objects (with multi-flag set)
1301  nlh->nlmsg_flags |= NLM_F_MULTI;
1302  nl_update_header(&cl, tot_encode_len);
1303  sock->AddNetlinkTxBuff(&cl);
1304  } else {
1305  KSyncSockTypeMap::SimulateResponse(seq_num, resp_code, 0);
1306  }
1307 }
1308 
1309 void MockDumpHandlerBase::SendGetResponse(uint32_t seq_num, int idx) {
1311  struct nl_client cl;
1312  int error = 0, ret;
1313  uint8_t *buf = NULL;
1314  uint32_t buf_len = 0, encode_len = 0;
1315  struct nlmsghdr *nlh;
1316 
1317  /* To simulate error code return the test code has to call
1318  * KSyncSockTypeMap::set_error_code() with required error code and
1319  * invoke get request */
1321  int ret_code = -KSyncSockTypeMap::error_code();
1322  ret_code &= ~VR_MESSAGE_DUMP_INCOMPLETE;
1323  KSyncSockTypeMap::SimulateResponse(seq_num, ret_code, 0);
1324  return;
1325  }
1326  Sandesh *req = Get(idx);
1327  if (req == NULL) {
1328  KSyncSockTypeMap::SimulateResponse(seq_num, -ENOENT, 0);
1329  return;
1330  }
1331  nl_init_generic_client_req(&cl, KSyncSock::GetNetlinkFamilyId());
1332  if ((ret = nl_build_header(&cl, &buf, &buf_len)) < 0) {
1333  LOG(DEBUG, "Error creating interface DUMP message : " << ret);
1334  nl_free(&cl);
1335  return;
1336  }
1337 
1338  nlh = (struct nlmsghdr *)cl.cl_buf;
1339  nlh->nlmsg_seq = seq_num;
1340 
1341  int resp_len = EncodeVrResponse(buf, buf_len, seq_num, 0);
1342  buf += resp_len;
1343  buf_len -= resp_len;
1344 
1345  encode_len = req->WriteBinary(buf, buf_len, &error);
1346  if (error) {
1347  KSyncSockTypeMap::SimulateResponse(seq_num, -ENOENT, 0);
1348  nl_free(&cl);
1349  return;
1350  }
1351  buf += encode_len;
1352  buf_len -= encode_len;
1353 
1354  nl_update_header(&cl, encode_len + resp_len);
1355  sock->AddNetlinkTxBuff(&cl);
1356 }
1357 
1360  KSyncSockTypeMap::ksync_map_if::const_iterator it;
1361  static vr_interface_req req;
1362 
1363  it = sock->if_map.find(idx);
1364  if (it != sock->if_map.end()) {
1365  req = it->second;
1366  return &req;
1367  }
1368  return NULL;
1369 }
1370 
1373  KSyncSockTypeMap::ksync_map_if::const_iterator it;
1374  static vr_interface_req req;
1375  int idx;
1376  vr_interface_req *orig_req;
1377  orig_req = static_cast<vr_interface_req *>(from_req);
1378 
1379  idx = orig_req->get_vifr_marker();
1380  it = sock->if_map.upper_bound(idx);
1381 
1382  if (it != sock->if_map.end()) {
1383  req = it->second;
1384  req.set_vifr_flags(orig_req->get_vifr_flags());
1385  return &req;
1386  }
1387  return NULL;
1388 }
1389 
1391  static int last_intf_id = 0;
1392  static int32_t last_if_flags = 0;
1394  KSyncSockTypeMap::ksync_map_if::const_iterator it;
1395  static vr_interface_req req, *r;
1396 
1397  r = dynamic_cast<vr_interface_req *>(input);
1398  if (r != NULL) {
1399  /* GetNext on vr_interface_req should return a dummy drop-stats object.
1400  * We need to store the interface index which will be used during
1401  * GetNext of IfDumpHandler when invoked with vr_drop_stats_req as
1402  * argument */
1403  last_intf_id = r->get_vifr_idx();
1404  last_if_flags = r->get_vifr_flags();
1405  if (r->get_vifr_flags() & VIF_FLAG_GET_DROP_STATS) {
1406  return &drop_stats_req;
1407  }
1408  }
1409  it = sock->if_map.upper_bound(last_intf_id);
1410 
1411  if (it != sock->if_map.end()) {
1412  req = it->second;
1413  req.set_vifr_flags(last_if_flags);
1414  return &req;
1415  }
1416  return NULL;
1417 }
1418 
1421  KSyncSockTypeMap::ksync_map_nh::const_iterator it;
1422  static vr_nexthop_req req;
1423 
1424  it = sock->nh_map.find(idx);
1425  if (it != sock->nh_map.end()) {
1426  req = it->second;
1427  return &req;
1428  }
1429  return NULL;
1430 }
1431 
1434  KSyncSockTypeMap::ksync_map_nh::const_iterator it;
1435  static vr_nexthop_req req;
1436  vr_nexthop_req *orig_req;
1437  orig_req = static_cast<vr_nexthop_req *>(from_req);
1438  int idx;
1439 
1440  idx = orig_req->get_nhr_marker();
1441  it = sock->nh_map.upper_bound(idx);
1442  if (it != sock->nh_map.end()) {
1443  req = it->second;
1444  return &req;
1445  }
1446  return NULL;
1447 }
1448 
1451  KSyncSockTypeMap::ksync_map_nh::const_iterator it;
1452  static vr_nexthop_req req, *r;
1453 
1454  r = static_cast<vr_nexthop_req *>(input);
1455  it = sock->nh_map.upper_bound(r->get_nhr_id());
1456 
1457  if (it != sock->nh_map.end()) {
1458  req = it->second;
1459  return &req;
1460  }
1461  return NULL;
1462 }
1463 
1466  KSyncSockTypeMap::ksync_map_mpls::const_iterator it;
1467  static vr_mpls_req req;
1468 
1469  it = sock->mpls_map.find(idx);
1470  if (it != sock->mpls_map.end()) {
1471  req = it->second;
1472  return &req;
1473  }
1474  return NULL;
1475 }
1476 
1479  KSyncSockTypeMap::ksync_map_mpls::const_iterator it;
1480  static vr_mpls_req req;
1481  vr_mpls_req *orig_req;
1482  orig_req = static_cast<vr_mpls_req *>(from_req);
1483  int idx;
1484 
1485  idx = orig_req->get_mr_marker();
1486  it = sock->mpls_map.upper_bound(idx);
1487 
1488  if (it != sock->mpls_map.end()) {
1489  req = it->second;
1490  return &req;
1491  }
1492  return NULL;
1493 }
1494 
1497  KSyncSockTypeMap::ksync_map_mpls::const_iterator it;
1498  static vr_mpls_req req, *r;
1499 
1500  r = static_cast<vr_mpls_req *>(input);
1501  it = sock->mpls_map.upper_bound(r->get_mr_label());
1502 
1503  if (it != sock->mpls_map.end()) {
1504  req = it->second;
1505  return &req;
1506  }
1507  return NULL;
1508 }
1509 
1512  KSyncSockTypeMap::ksync_map_vrf::const_iterator it;
1513  static vr_vrf_req req;
1514 
1515  it = sock->vrf_map.find(idx);
1516  if (it != sock->vrf_map.end()) {
1517  req = it->second;
1518  return &req;
1519  }
1520  return NULL;
1521 }
1522 
1525  KSyncSockTypeMap::ksync_map_vrf::const_iterator it;
1526  static vr_vrf_req req;
1527  vr_vrf_req *orig_req;
1528  orig_req = static_cast<vr_vrf_req *>(from_req);
1529  int idx;
1530 
1531  idx = orig_req->get_vrf_marker();
1532  it = sock->vrf_map.upper_bound(idx);
1533 
1534  if (it != sock->vrf_map.end()) {
1535  req = it->second;
1536  return &req;
1537  }
1538  return NULL;
1539 }
1540 
1543  KSyncSockTypeMap::ksync_map_vrf::const_iterator it;
1544  static vr_vrf_req req, *r;
1545 
1546  r = static_cast<vr_vrf_req *>(input);
1547  it = sock->vrf_map.upper_bound(r->get_vrf_idx());
1548 
1549  if (it != sock->vrf_map.end()) {
1550  req = it->second;
1551  return &req;
1552  }
1553  return NULL;
1554 }
1555 
1558  KSyncSockTypeMap::ksync_map_mirror::const_iterator it;
1559  static vr_mirror_req req;
1560 
1561  it = sock->mirror_map.find(idx);
1562  if (it != sock->mirror_map.end()) {
1563  req = it->second;
1564  return &req;
1565  }
1566  return NULL;
1567 }
1568 
1571  KSyncSockTypeMap::ksync_map_mirror::const_iterator it;
1572  static vr_mirror_req req;
1573  vr_mirror_req *orig_req;
1574  orig_req = static_cast<vr_mirror_req *>(from_req);
1575  int idx;
1576 
1577  idx = orig_req->get_mirr_marker();
1578  it = sock->mirror_map.upper_bound(idx);
1579 
1580  if (it != sock->mirror_map.end()) {
1581  req = it->second;
1582  return &req;
1583  }
1584  return NULL;
1585 }
1586 
1589  KSyncSockTypeMap::ksync_map_mirror::const_iterator it;
1590  static vr_mirror_req req, *r;
1591 
1592  r = static_cast<vr_mirror_req *>(input);
1593  it = sock->mirror_map.upper_bound(r->get_mirr_index());
1594 
1595  if (it != sock->mirror_map.end()) {
1596  req = it->second;
1597  return &req;
1598  }
1599  return NULL;
1600 }
1601 
1604  KSyncSockTypeMap::ksync_rt_tree::const_iterator it;
1605  static vr_route_req req;
1606  vr_route_req *orig_req, key;
1607  orig_req = static_cast<vr_route_req *>(from_req);
1608 
1609  key.set_rtr_family(orig_req->get_rtr_family());
1610  key.set_rtr_vrf_id(orig_req->get_rtr_vrf_id());
1611  if (orig_req->get_rtr_marker().size() || orig_req->get_rtr_mac().size()) {
1612  if (orig_req->get_rtr_family() == AF_BRIDGE) {
1613  key.set_rtr_mac(orig_req->get_rtr_mac());
1614  } else {
1615  key.set_rtr_prefix(orig_req->get_rtr_marker());
1616  key.set_rtr_prefix_len(orig_req->get_rtr_marker_plen());
1617  }
1618  it = sock->rt_tree.upper_bound(key);
1619  } else {
1620  std::vector<int8_t> rtr_prefix;
1621  if (orig_req->get_rtr_family() == AF_BRIDGE) {
1622  key.set_rtr_mac(rtr_prefix);
1623  } else {
1624  key.set_rtr_prefix(rtr_prefix);
1625  key.set_rtr_prefix_len(0);
1626  }
1627  it = sock->rt_tree.lower_bound(key);
1628  }
1629 
1630 
1631  if (it != sock->rt_tree.end()) {
1632  if ((it->get_rtr_vrf_id() != orig_req->get_rtr_vrf_id()) ||
1633  (it->get_rtr_family() != orig_req->get_rtr_family())) {
1634  return NULL;
1635  }
1636  req = *it;
1637  return &req;
1638  }
1639  return NULL;
1640 }
1641 
1644  KSyncSockTypeMap::ksync_rt_tree::const_iterator it;
1645  static vr_route_req req, *r, key;
1646 
1647  r = static_cast<vr_route_req *>(input);
1648 
1649  key.set_rtr_vrf_id(r->get_rtr_vrf_id());
1650  key.set_rtr_family(r->get_rtr_family());
1651  if (r->get_rtr_family() == AF_BRIDGE) {
1652  key.set_rtr_mac(r->get_rtr_mac());
1653  } else {
1654  key.set_rtr_prefix(r->get_rtr_prefix());
1655  key.set_rtr_prefix_len(r->get_rtr_prefix_len());
1656  }
1657  it = sock->rt_tree.upper_bound(key);
1658 
1659  if (it != sock->rt_tree.end()) {
1660  if ((it->get_rtr_vrf_id() != r->get_rtr_vrf_id()) ||
1661  (it->get_rtr_family() != r->get_rtr_family())) {
1662  return NULL;
1663  }
1664  req = *it;
1665  return &req;
1666  }
1667  return NULL;
1668 }
1669 
1672  KSyncSockTypeMap::ksync_vrf_assign_tree::const_iterator it;
1673  static vr_vrf_assign_req req;
1674  vr_vrf_assign_req *orig_req, key;
1675  orig_req = static_cast<vr_vrf_assign_req *>(from_req);
1676 
1677  key.set_var_vif_index(orig_req->get_var_vif_index());
1678  key.set_var_vlan_id(orig_req->get_var_marker());
1679  it = sock->vrf_assign_tree.upper_bound(key);
1680 
1681  if (it != sock->vrf_assign_tree.end()) {
1682  req = *it;
1683  return &req;
1684  }
1685  return NULL;
1686 }
1687 
1690  KSyncSockTypeMap::ksync_vrf_assign_tree::const_iterator it;
1691  static vr_vrf_assign_req req, *r, key;
1692 
1693  r = static_cast<vr_vrf_assign_req *>(input);
1694 
1695  key.set_var_vif_index(r->get_var_vif_index());
1696  key.set_var_vlan_id(r->get_var_vlan_id());
1697  it = sock->vrf_assign_tree.upper_bound(key);
1698 
1699  if (it != sock->vrf_assign_tree.end()) {
1700  req = *it;
1701  return &req;
1702  }
1703  return NULL;
1704 }
1705 
1708  KSyncSockTypeMap::ksync_map_vrf_stats::const_iterator it;
1709  static vr_vrf_stats_req req;
1710 
1711  it = sock->vrf_stats_map.find(idx);
1712  if (it != sock->vrf_stats_map.end()) {
1713  req = it->second;
1714  return &req;
1715  }
1716  return NULL;
1717 }
1718 
1721  KSyncSockTypeMap::ksync_map_vrf_stats::const_iterator it;
1722  static vr_vrf_stats_req req;
1723  int idx;
1724  vr_vrf_stats_req *orig_req;
1725  orig_req = static_cast<vr_vrf_stats_req *>(from_req);
1726 
1727  idx = orig_req->get_vsr_marker();
1728  it = sock->vrf_stats_map.upper_bound(idx);
1729 
1730  if (it != sock->vrf_stats_map.end()) {
1731  req = it->second;
1732  return &req;
1733  }
1734  return NULL;
1735 }
1736 
1739  KSyncSockTypeMap::ksync_map_vrf_stats::const_iterator it;
1740  static vr_vrf_stats_req req, *r;
1741 
1742  r = static_cast<vr_vrf_stats_req *>(input);
1743  it = sock->vrf_stats_map.upper_bound(r->get_vsr_vrf());
1744 
1745  if (it != sock->vrf_stats_map.end()) {
1746  req = it->second;
1747  return &req;
1748  }
1749  return NULL;
1750 }
1751 
1754  KSyncSockTypeMap::ksync_map_vxlan::const_iterator it;
1755  static vr_vxlan_req req;
1756 
1757  it = sock->vxlan_map.find(idx);
1758  if (it != sock->vxlan_map.end()) {
1759  req = it->second;
1760  return &req;
1761  }
1762  return NULL;
1763 }
1764 
1767  KSyncSockTypeMap::ksync_map_vxlan::const_iterator it;
1768  static vr_vxlan_req req;
1769  vr_vxlan_req *orig_req;
1770  orig_req = static_cast<vr_vxlan_req *>(from_req);
1771  int idx;
1772 
1773  idx = orig_req->get_vxlanr_vnid();
1774  it = sock->vxlan_map.upper_bound(idx);
1775 
1776  if (it != sock->vxlan_map.end()) {
1777  req = it->second;
1778  return &req;
1779  }
1780  return NULL;
1781 }
1782 
1785  KSyncSockTypeMap::ksync_map_vxlan::const_iterator it;
1786  static vr_vxlan_req req, *r;
1787 
1788  r = static_cast<vr_vxlan_req *>(input);
1789  it = sock->vxlan_map.upper_bound(r->get_vxlanr_vnid());
1790 
1791  if (it != sock->vxlan_map.end()) {
1792  req = it->second;
1793  return &req;
1794  }
1795  return NULL;
1796 }
static int RouteCount()
void SetBlockMsgProcessing(bool enable)
ksync_rt_tree rt_tree
virtual uint32_t GetSeqno(char *data)
virtual Sandesh * GetFirst(Sandesh *)
static int GetNetlinkFamilyId()
Definition: ksync_sock.h:391
static void VrfStatsDelete(int vrf_id)
static KSyncSockTypeMap * GetKSyncSockTypeMap()
static int IfCount()
void ProcessSandesh(const uint8_t *, std::size_t, KSyncUserSockContext *)
virtual void RouteMsgHandler(vr_route_req *req)
virtual Sandesh * GetFirst(Sandesh *)
static void SetUnderlaySourcePort(int idx, int port)
vr_drop_stats_req drop_stats
virtual Sandesh * GetNext(Sandesh *)
void SendGetResponse(uint32_t seq_num, int idx)
static vr_flow_entry * GetFlowEntry(int idx)
virtual std::size_t SendTo(KSyncBufferList *iovec, uint32_t seq_no)
ksync_map_mirror mirror_map
virtual int32_t WriteBinary(u_int8_t *buf, u_int32_t buf_len, int *error)
Definition: sandesh.cc:571
virtual void VrfMsgHandler(vr_vrf_req *req)
virtual bool BulkDecoder(char *data, KSyncBulkSandeshContext *ctxt)
ksync_map_nh nh_map
static void SetFlowTcpFlags(int idx, uint16_t flags)
boost::asio::ip::address IpAddress
Definition: address.h:13
static void IfStatsUpdate(int, int, int, int, int, int, int)
virtual Sandesh * Get(int idx)
virtual void Receive(boost::asio::mutable_buffers_1)
virtual Sandesh * GetNext(Sandesh *)
virtual Sandesh * Get(int idx)
ksync_map_vrf_stats vrf_stats_map
virtual Sandesh * GetFirst(Sandesh *)
static void SetDropStats(const vr_drop_stats_req &req)
std::vector< boost::asio::mutable_buffers_1 > KSyncBufferList
Definition: ksync_sock.h:37
virtual Sandesh * GetFirst(Sandesh *)
virtual Sandesh * GetFirst(Sandesh *)
virtual void DropStatsMsgHandler(vr_drop_stats_req *req)
static int NHCount()
void AddNetlinkTxBuff(struct nl_client *cl)
virtual Sandesh * GetNext(Sandesh *)
vr_bridge_entry * GetBridgeEntry(int idx)
static void SetVRouterOps(const vrouter_ops &req)
static void IoVectorToData(std::string &data, KSyncBufferList *iovec)
static void Shutdown()
static void FlowMmapFree()
static void VxlanAdd(int id)
virtual Sandesh * GetFirst(Sandesh *)
ksync_map_vrf vrf_map
tbb::mutex ctx_queue_lock_
virtual Sandesh * GetFirst(Sandesh *)
static void ResetEvictedFlag(int idx)
virtual Sandesh * Get(int idx)
ksync_map_if if_map
static void MplsDelete(int id)
ksync_map_vxlan vxlan_map
virtual void IfMsgHandler(vr_interface_req *req)
ksync_vrf_assign_tree vrf_assign_tree
static void MirrorAdd(int id)
virtual void VrfStatsMsgHandler(vr_vrf_stats_req *req)
static int MplsCount()
static void InterfaceDelete(int id)
static void VrfStatsAdd(int vrf_id)
static void SetSockTableEntry(KSyncSock *sock)
Definition: ksync_sock.cc:264
static void VrfAssignAdd(vr_vrf_assign_req &req)
static void MirrorDelete(int id)
virtual Sandesh * GetNext(Sandesh *)
int EncodeVrResponse(uint8_t *buf, int buf_len, uint32_t seq_num, int code)
boost::function< void(const boost::system::error_code &, size_t)> HandlerCb
Definition: ksync_sock.h:326
virtual Sandesh * GetNext(Sandesh *)
int GetKSyncError(KSyncSockEntryType type)
static void SetTcpFlag(int idx, uint32_t flags)
virtual Sandesh * GetNext(Sandesh *)
static void Init(bool use_work_queue, const std::string &cpu_pin_policy)
Definition: ksync_sock.cc:226
void UpdateBridgeEntryInactiveFlag(int idx, bool set)
vr_bridge_entry * BridgeMmapAlloc(int size)
virtual void VxLanMsgHandler(vr_vxlan_req *req)
static void IfStatsSet(int, int, int, int, int, int, int)
static int32_t ReceiveBinaryMsgOne(u_int8_t *buf, u_int32_t buf_len, int *error, SandeshContext *client_context)
Definition: sandesh.cc:642
virtual Sandesh * GetNext(Sandesh *)
static void FlowNatResponse(uint32_t seq_num, vr_flow_req *req, int code=0)
ksync_map_flow flow_map
ksync_map_mpls mpls_map
static void Init(boost::asio::io_context &ios)
static int VxLanCount()
virtual bool Validate(char *data)
static void RouteDelete(vr_route_req &req)
virtual void FlowMsgHandler(vr_flow_req *req)
virtual void QosConfigMsgHandler(vr_qos_map_req *req)
virtual bool Decoder(char *data, AgentSandeshContext *ctxt)
virtual void VrfAssignMsgHandler(vr_vrf_assign_req *req)
virtual Sandesh * GetFirst(Sandesh *)
static int error_code()
virtual Sandesh * Get(int idx)
virtual Sandesh * GetNext(Sandesh *)
static void InterfaceAdd(int id, int flags=0, int mac_size=6)
static void NHDelete(int id)
static void NHAdd(int id, int flags=0)
void SendDumpResponse(uint32_t seq_num, Sandesh *)
static KSyncSockTypeMap * singleton_
static void MplsAdd(int id)
static void SetFlowEntry(vr_flow_req *req, bool set)
virtual Sandesh * GetFirst(Sandesh *)
virtual bool IsMoreData(char *data)
virtual Sandesh * GetNext(Sandesh *)
static void VrfAssignDelete(vr_vrf_assign_req &req)
void InitNetlinkDoneMsg(struct nlmsghdr *nlh, uint32_t seq_num)
virtual void ForwardingClassMsgHandler(vr_fc_map_req *req)
virtual void NHMsgHandler(vr_nexthop_req *req)
#define LOG(_Level, _Msg)
Definition: logging.h:33
static vr_flow_entry * FlowMmapAlloc(int size)
void SetBridgeEntry(uint32_t idx, vr_route_req *req, bool set)
static void VrfStatsUpdate(int vrf_id, const vr_vrf_stats_req &req)
virtual Sandesh * Get(int idx)
static void VxlanDelete(int id)
static int error_code_
void U64ToIp(uint64_t sip_u, uint64_t sip_l, uint64_t dip_u, uint64_t dip_l, int family, IpAddress *sip, IpAddress *dip)
virtual void MirrorMsgHandler(vr_mirror_req *req)
virtual void MplsMsgHandler(vr_mpls_req *req)
static void IncrFlowStats(int idx, int pkts, int bytes)
static vr_flow_entry * flow_table_
void DisableReceiveQueue(bool disable)
virtual void AsyncReceive(boost::asio::mutable_buffers_1, HandlerCb)
static void RouteAdd(vr_route_req &req)
static void SetEvictedFlag(int idx)
vrouter_ops ksync_vrouter_ops
virtual void AsyncSendTo(KSyncBufferList *iovec, uint32_t seq_no, HandlerCb cb)
static void SimulateResponse(uint32_t, int, int)
virtual Sandesh * Get(int idx)
virtual void VrouterOpsMsgHandler(vrouter_ops *req)
virtual Sandesh * Get(int idx)
ksync_map_ctx_queue ctx_queue_
static void SetOFlowStats(int idx, uint8_t pkts, uint16_t bytes)