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 static int IoVectorToData(char *data, uint32_t len, KSyncBufferList *iovec) {
559  KSyncBufferList::iterator it = iovec->begin();
560  int offset = 0;
561  while (it != iovec->end()) {
562  unsigned char *buf = boost::asio::buffer_cast<unsigned char *>(*it);
563  assert((offset + boost::asio::buffer_size(*it)) < len);
564  memcpy(data + offset, buf, boost::asio::buffer_size(*it));
565  offset += boost::asio::buffer_size(*it);
566  it++;
567  }
568  return offset;
569 }
570 
571 //send or store in map
572 void KSyncSockTypeMap::AsyncSendTo(KSyncBufferList *iovec, uint32_t seq_no,
573  HandlerCb cb) {
574  char data[4096];
575  int data_len = IoVectorToData(data, 4096, iovec);
576 
577  KSyncUserSockContext ctx(seq_no);
578  //parse and store info in map [done in Process() callbacks]
579  ProcessSandesh((const uint8_t *)(data), data_len, &ctx);
580 }
581 
582 //send or store in map
583 std::size_t KSyncSockTypeMap::SendTo(KSyncBufferList *iovec, uint32_t seq_no) {
584  char data[4096];
585  int data_len = IoVectorToData(data, 4096, iovec);
586  KSyncUserSockContext ctx(seq_no);
587  //parse and store info in map [done in Process() callbacks]
588  ProcessSandesh((const uint8_t *)(data), data_len, &ctx);
589  return 0;
590 }
591 
592 //receive msgs from datapath
593 void KSyncSockTypeMap::AsyncReceive(mutable_buffers_1 buf, HandlerCb cb) {
594  sock_.async_receive_from(buf, local_ep_, cb);
595 }
596 
597 //receive msgs from datapath
598 void KSyncSockTypeMap::Receive(mutable_buffers_1 buf) {
599  sock_.receive(buf);
600 }
601 
602 vr_flow_entry *KSyncSockTypeMap::FlowMmapAlloc(int size) {
603  flow_table_ = (vr_flow_entry *)malloc(size);
604  return flow_table_;
605 }
606 
608  if (flow_table_) {
609  free(flow_table_);
610  flow_table_ = NULL;
611  }
612 }
613 
614 vr_flow_entry *KSyncSockTypeMap::GetFlowEntry(int idx) {
615  return &flow_table_[idx];
616 }
617 
618 void KSyncSockTypeMap::SetFlowEntry(vr_flow_req *req, bool set) {
619  uint32_t idx = req->get_fr_index();
620 
621  vr_flow_entry *f = &flow_table_[idx];
622  if (!set) {
623  f->fe_flags &= ~VR_FLOW_FLAG_ACTIVE;
624  f->fe_stats.flow_bytes = 0;
625  f->fe_stats.flow_packets = 0;
626  f->fe_gen_id = 0;
627  return;
628  }
629 
630  int family = (req->get_fr_family() == AF_INET)? Address::INET :
632  IpAddress sip;
633  IpAddress dip;
634  U64ToIp(req->get_fr_flow_sip_u(), req->get_fr_flow_sip_l(),
635  req->get_fr_flow_dip_u(), req->get_fr_flow_dip_l(),
636  family, &sip, &dip);
637  f->fe_flags = VR_FLOW_FLAG_ACTIVE;
638  f->fe_stats.flow_bytes = 30;
639  f->fe_stats.flow_packets = 1;
640  f->fe_gen_id = req->get_fr_gen_id();
641  if (sip.is_v4()) {
642  f->fe_key.flow4_sip = htonl(sip.to_v4().to_ulong());
643  f->fe_key.flow4_dip = htonl(dip.to_v4().to_ulong());
644  }
645  if (family == Address::INET) {
646  f->fe_key.flow4_nh_id = req->get_fr_flow_nh_id();
647  } else {
648  f->fe_key.flow6_nh_id = req->get_fr_flow_nh_id();
649  }
650  f->fe_key.flow_family = req->get_fr_family();
651  f->fe_key.flow_sport = req->get_fr_flow_sport();
652  f->fe_key.flow_dport = req->get_fr_flow_dport();
653  f->fe_key.flow_nh_id = req->get_fr_flow_nh_id();
654  f->fe_key.flow_proto = req->get_fr_flow_proto();
655 }
656 
658  vr_flow_entry *f = &flow_table_[idx];
659  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
660  f->fe_flags |= VR_FLOW_FLAG_EVICTED;
661  }
662 }
663 
665  vr_flow_entry *f = &flow_table_[idx];
666  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
667  f->fe_flags &= ~VR_FLOW_FLAG_EVICTED;
668  }
669 }
670 
671 
672 void KSyncSockTypeMap::IncrFlowStats(int idx, int pkts, int bytes) {
673  vr_flow_entry *f = &flow_table_[idx];
674  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
675  f->fe_stats.flow_bytes += bytes;
676  f->fe_stats.flow_packets += pkts;
677  }
678 }
679 
680 void KSyncSockTypeMap::SetTcpFlag(int idx, uint32_t flags) {
681  vr_flow_entry *f = &flow_table_[idx];
682  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
683  f->fe_tcp_flags = flags;
684  }
685 }
686 
687 void KSyncSockTypeMap::SetFlowTcpFlags(int idx, uint16_t flags) {
688  vr_flow_entry *f = &flow_table_[idx];
689  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
690  f->fe_tcp_flags = flags;
691  }
692 }
693 
695  vr_flow_entry *f = &flow_table_[idx];
696  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
697  f->fe_udp_src_port = port;
698  }
699 }
700 
701 void KSyncSockTypeMap::SetOFlowStats(int idx, uint8_t pkts, uint16_t bytes) {
702  vr_flow_entry *f = &flow_table_[idx];
703  if (f->fe_flags & VR_FLOW_FLAG_ACTIVE) {
704  f->fe_stats.flow_bytes_oflow = bytes;
705  f->fe_stats.flow_packets_oflow = pkts;
706  }
707 }
708 
709 vr_bridge_entry *KSyncSockTypeMap::BridgeMmapAlloc(int size) {
710  bridge_table_ = (vr_bridge_entry *)malloc(size);
711  memset(bridge_table_, 0, size);
712  return bridge_table_;
713 }
714 
716  if (bridge_table_) {
717  free(bridge_table_);
718  bridge_table_ = NULL;
719  }
720 }
721 
722 vr_bridge_entry *KSyncSockTypeMap::GetBridgeEntry(int idx) {
723  return &bridge_table_[idx];
724 }
725 
726 void KSyncSockTypeMap::SetBridgeEntry(uint32_t idx, vr_route_req *req,
727  bool set) {
728  vr_bridge_entry *be = &bridge_table_[idx];
729  if (!set) {
730  be->be_packets = 0;
731  return;
732  }
733 
734  if (be->be_packets == 0) {
735  be->be_packets = 1;
736  }
737  vr_bridge_entry_key *key = &be->be_key;
738 
739  //Copy VRF and mac
740  key->be_vrf_id = req->get_rtr_vrf_id();
741 
742  uint8_t i = 0;
743  const std::vector<signed char> &prefix = req->get_rtr_mac();
744  for(std::vector<signed char>::const_iterator it = prefix.begin();
745  it != prefix.end(); ++it) {
746  key->be_mac[i] = ((uint8_t) *it);
747  i++;
748  }
749 }
750 
752  vr_bridge_entry *be = &bridge_table_[idx];
753  if (set) {
754  be->be_flags |= VR_BE_MAC_NEW_FLAG;
755  } else {
756  be->be_flags &= ~VR_BE_MAC_NEW_FLAG;
757  }
758 }
759 
760 //init ksync map
761 void KSyncSockTypeMap::Init(boost::asio::io_context &ios) {
762  assert(singleton_ == NULL);
763 
764  singleton_ = new KSyncSockTypeMap(ios);
765  KSyncSock::SetSockTableEntry(singleton_);
766  KSyncSock::Init(true, "disabled");
767 
768  singleton_->local_ep_.address
769  (boost::asio::ip::address::from_string("127.0.0.1"));
770  singleton_->local_ep_.port(0);
771  singleton_->sock_.open(boost::asio::ip::udp::v4());
772  singleton_->sock_.bind(singleton_->local_ep_);
773  singleton_->local_ep_ = singleton_->sock_.local_endpoint();
774 }
775 
777  delete singleton_;
778  singleton_ = NULL;
779 }
780 
782  while (!ctx_queue_.empty()) {
783  ctx_queue_.front()->Process();
784  delete ctx_queue_.front();
785  ctx_queue_.pop();
786  }
787  PurgeTxBuffer();
788 }
789 
791  tbb::mutex::scoped_lock lock(ctx_queue_lock_);
792  if (block_msg_processing_ != enable) {
793  block_msg_processing_ = enable;
794  if (!block_msg_processing_) {
795  PurgeBlockedMsg();
796  }
797  }
798 }
799 
802 
803  //delete from map if command is delete
804  if (req_->get_h_op() == sandesh_op::DEL) {
805  sock->if_map.erase(req_->get_vifr_idx());
806  } else if (req_->get_h_op() == sandesh_op::DUMP) {
807  IfDumpHandler dump;
808  dump.SendDumpResponse(GetSeqNum(), req_);
809  return;
810  } else if (req_->get_h_op() == sandesh_op::GET) {
811  IfDumpHandler dump;
812  dump.SendGetResponse(GetSeqNum(), req_->get_vifr_idx());
813  return;
814  } else {
815  //store in the map
816  vr_interface_req if_info(*req_);
817  sock->if_map[req_->get_vifr_idx()] = if_info;
818  }
819  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
820 }
821 
822 void KSyncUserSockContext::IfMsgHandler(vr_interface_req *req) {
824  KSyncUserSockIfContext *ifctx = new KSyncUserSockIfContext(GetSeqNum(), req);
825 
826  if (sock->IsBlockMsgProcessing()) {
827  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
828  sock->ctx_queue_.push(ifctx);
829  } else {
830  ifctx->Process();
831  delete ifctx;
832  }
833 }
834 
837  uint16_t flags = 0;
839 
840  flags = req_->get_fr_flags();
841  //delete from map if command is delete
842  if (!flags) {
843  sock->flow_map.erase(req_->get_fr_index());
844  //Deactivate the flow-entry in flow mmap
845  KSyncSockTypeMap::SetFlowEntry(req_, false);
846  } else {
847  uint32_t fwd_flow_idx = req_->get_fr_index();
848  if (fwd_flow_idx == 0xFFFFFFFF) {
849  if (flow_error == 0) {
850  /* Allocate entry only of no error case */
851  if (sock->is_incremental_index()) {
852  /* Send reverse-flow index as one more than fwd-flow index */
853  fwd_flow_idx = req_->get_fr_rindex() + 1;
854  } else {
855  fwd_flow_idx = rand() % 20000;
856  /* Reserve first 20000 indexes for forwarding flow
857  * Reverse flow indexes will start from 20000 always
858  */
859  fwd_flow_idx += 20000;
860  }
861  /* If the randomly allocated index is used already then
862  * find out the next randon index which is free
863  */
864  if (sock->is_incremental_index()) {
865  if (sock->flow_map.find(fwd_flow_idx) != sock->flow_map.end()) {
866  //sock->SimulateResponse(GetSeqNum(), -EEXIST, 0);
867  int code = -EEXIST;
868  req_->set_fr_index(fwd_flow_idx);
869  req_->set_fr_gen_id((fwd_flow_idx % 255));
870  KSyncSockTypeMap::FlowNatResponse(GetSeqNum(), req_, code);
871  return;
872  }
873  } else {
874  while (sock->flow_map.find(fwd_flow_idx) != sock->flow_map.end()) {
875  fwd_flow_idx = rand() % 20000;
876  /* Reserve first 20000 indexes for forwarding flow
877  * Reverse flow indexes will start from 20000 always
878  */
879  fwd_flow_idx += 20000;
880  }
881  }
882  req_->set_fr_index(fwd_flow_idx);
883  req_->set_fr_gen_id((fwd_flow_idx % 255));
884  }
885  }
886 
887  if (fwd_flow_idx != 0xFFFFFFFF) {
888  //store info from binary sandesh message
889  vr_flow_req flow_info(*req_);
890 
891  sock->flow_map[req_->get_fr_index()] = flow_info;
892 
893  //Activate the flow-entry in flow mmap
894  KSyncSockTypeMap::SetFlowEntry(req_, true);
895  }
896 
897  // For NAT flow, don't send vr_response, instead send
898  // vr_flow_req with index of reverse_flow
899  KSyncSockTypeMap::FlowNatResponse(GetSeqNum(), req_);
900  return;
901  }
902  KSyncSockTypeMap::FlowNatResponse(GetSeqNum(), req_);
903 }
904 
905 void KSyncUserSockContext::FlowMsgHandler(vr_flow_req *req) {
907  KSyncUserSockFlowContext *flowctx = new KSyncUserSockFlowContext(GetSeqNum(), req);
908 
909  if (sock->IsBlockMsgProcessing()) {
910  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
911  sock->ctx_queue_.push(flowctx);
912  } else {
913  flowctx->Process();
914  delete flowctx;
915  }
916 }
917 
920 
921  //delete from map if command is delete
922  if (req_->get_h_op() == sandesh_op::DEL) {
923  sock->nh_map.erase(req_->get_nhr_id());
924  } else if (req_->get_h_op() == sandesh_op::DUMP) {
925  NHDumpHandler dump;
926  dump.SendDumpResponse(GetSeqNum(), req_);
927  return;
928  } else if (req_->get_h_op() == sandesh_op::GET) {
929  NHDumpHandler dump;
930  dump.SendGetResponse(GetSeqNum(), req_->get_nhr_id());
931  return;
932  } else {
933  //store in the map
934  vr_nexthop_req nh_info(*req_);
935  sock->nh_map[req_->get_nhr_id()] = nh_info;
936  }
937  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
938 }
939 
940 void KSyncUserSockContext::NHMsgHandler(vr_nexthop_req *req) {
942  KSyncUserSockNHContext *nhctx = new KSyncUserSockNHContext(GetSeqNum(), req);
943 
944  if (sock->IsBlockMsgProcessing()) {
945  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
946  sock->ctx_queue_.push(nhctx);
947  } else {
948  nhctx->Process();
949  delete nhctx;
950  }
951 }
952 
955 
956  //delete from map mpls command is delete
957  if (req_->get_h_op() == sandesh_op::DEL) {
958  sock->mpls_map.erase(req_->get_mr_label());
959  } else if (req_->get_h_op() == sandesh_op::DUMP) {
960  MplsDumpHandler dump;
961  dump.SendDumpResponse(GetSeqNum(), req_);
962  return;
963  } else if (req_->get_h_op() == sandesh_op::GET) {
964  MplsDumpHandler dump;
965  dump.SendGetResponse(GetSeqNum(), req_->get_mr_label());
966  return;
967  } else {
968  //store in the map
969  vr_mpls_req mpls_info(*req_);
970  sock->mpls_map[req_->get_mr_label()] = mpls_info;
971  }
972  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
973 }
974 
975 void KSyncUserSockContext::MplsMsgHandler(vr_mpls_req *req) {
977  KSyncUserSockMplsContext *mplsctx = new KSyncUserSockMplsContext(GetSeqNum(), req);
978 
979  if (sock->IsBlockMsgProcessing()) {
980  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
981  sock->ctx_queue_.push(mplsctx);
982  } else {
983  mplsctx->Process();
984  delete mplsctx;
985  }
986 }
987 
990 
991  //delete from the route tree, if the command is delete
992  if (req_->get_h_op() == sandesh_op::DEL) {
993  if (req_->get_rtr_family() == AF_BRIDGE) {
994  sock->UpdateBridgeEntryInactiveFlag(req_->get_rtr_index(), false);
995  }
996  sock->rt_tree.erase(*req_);
997  } else if (req_->get_h_op() == sandesh_op::DUMP) {
998  RouteDumpHandler dump;
999  sock->SetBridgeEntry(req_->get_rtr_index(), req_, false);
1000  dump.SendDumpResponse(GetSeqNum(), req_);
1001  return;
1002  } else {
1003  sock->RouteAdd(*req_);
1004  }
1005  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1006 }
1007 
1008 void KSyncUserSockContext::RouteMsgHandler(vr_route_req *req) {
1010  KSyncUserSockRouteContext *rtctx = new KSyncUserSockRouteContext(GetSeqNum(), req);
1011 
1012  if (sock->IsBlockMsgProcessing()) {
1013  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1014  sock->ctx_queue_.push(rtctx);
1015  } else {
1016  rtctx->Process();
1017  delete rtctx;
1018  }
1019 }
1020 
1022  assert(0);
1023 }
1024 
1026  assert(0);
1027 }
1028 
1029 void KSyncUserSockContext::MirrorMsgHandler(vr_mirror_req *req) {
1031 
1032  //delete from map if command is delete
1033  if (req->get_h_op() == sandesh_op::DEL) {
1034  sock->mirror_map.erase(req->get_mirr_index());
1035  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1036  return;
1037  }
1038 
1039  if (req->get_h_op() == sandesh_op::DUMP) {
1040  MirrorDumpHandler dump;
1041  dump.SendDumpResponse(GetSeqNum(), req);
1042  return;
1043  }
1044 
1045  if (req->get_h_op() == sandesh_op::GET) {
1046  MirrorDumpHandler dump;
1047  dump.SendGetResponse(GetSeqNum(), req->get_mirr_index());
1048  return;
1049  }
1050 
1051  //store in the map
1052  vr_mirror_req mirror_info(*req);
1053  sock->mirror_map[req->get_mirr_index()] = mirror_info;
1054  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1055 }
1056 
1059 
1060  //delete from map vxlan command is delete
1061  if (req_->get_h_op() == sandesh_op::DEL) {
1062  sock->vxlan_map.erase(req_->get_vxlanr_vnid());
1063  } else if (req_->get_h_op() == sandesh_op::DUMP) {
1064  VxLanDumpHandler dump;
1065  dump.SendDumpResponse(GetSeqNum(), req_);
1066  return;
1067  } else if (req_->get_h_op() == sandesh_op::GET) {
1068  VxLanDumpHandler dump;
1069  dump.SendGetResponse(GetSeqNum(), req_->get_vxlanr_vnid());
1070  return;
1071  } else {
1072  //store in the map
1073  vr_vxlan_req vxlan_info(*req_);
1074  sock->vxlan_map[req_->get_vxlanr_vnid()] = vxlan_info;
1075  }
1076  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1077 }
1078 
1079 void KSyncUserSockContext::VxLanMsgHandler(vr_vxlan_req *req) {
1081  KSyncUserSockVxLanContext *vxlanctx =
1082  new KSyncUserSockVxLanContext(GetSeqNum(), req);
1083 
1084  if (sock->IsBlockMsgProcessing()) {
1085  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1086  sock->ctx_queue_.push(vxlanctx);
1087  } else {
1088  vxlanctx->Process();
1089  delete vxlanctx;
1090  }
1091 }
1092 
1093 
1096  if (req_->get_h_op() == sandesh_op::GET) {
1097  VRouterOpsDumpHandler dump;
1098  sock->ksync_vrouter_ops.set_vo_mpls_labels(10000);
1099  dump.SendGetResponse(GetSeqNum(), 0);
1100  return;
1101  }
1102 }
1105  KSyncUserVrouterOpsContext *vrouter_ops =
1106  new KSyncUserVrouterOpsContext(GetSeqNum(), req);
1107 
1108  if (sock->IsBlockMsgProcessing()) {
1109  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1110  sock->ctx_queue_.push(vrouter_ops);
1111  } else {
1112  vrouter_ops->Process();
1113  delete vrouter_ops;
1114  }
1115 }
1116 
1119 
1120  //delete from the vrf assign tree, if the command is delete
1121  if (req_->get_h_op() == sandesh_op::DEL) {
1122  sock->vrf_assign_tree.erase(*req_);
1123  } else if (req_->get_h_op() == sandesh_op::DUMP) {
1124  VrfAssignDumpHandler dump;
1125  dump.SendDumpResponse(GetSeqNum(), req_);
1126  return;
1127  } else {
1128  //store in the vrf assign tree
1129  std::pair<std::set<vr_vrf_assign_req>::iterator, bool> ret;
1130  ret = sock->vrf_assign_tree.insert(*req_);
1131 
1132  /* If insertion fails, remove the existing entry and add the new one */
1133  if (ret.second == false) {
1134  int del_count = sock->vrf_assign_tree.erase(*req_);
1135  assert(del_count);
1136  ret = sock->vrf_assign_tree.insert(*req_);
1137  assert(ret.second == true);
1138  }
1139  }
1140  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1141 }
1142 
1143 void KSyncUserSockContext::VrfAssignMsgHandler(vr_vrf_assign_req *req) {
1146  new KSyncUserSockVrfAssignContext(GetSeqNum(), req);
1147 
1148  if (sock->IsBlockMsgProcessing()) {
1149  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1150  sock->ctx_queue_.push(ctx);
1151  } else {
1152  ctx->Process();
1153  delete ctx;
1154  }
1155 }
1156 
1159 
1160  //delete from map if command is delete
1161  if (req_->get_h_op() == sandesh_op::DEL) {
1162  sock->vrf_map.erase(req_->get_vrf_idx());
1163  } else if (req_->get_h_op() == sandesh_op::DUMP) {
1164  VrfDumpHandler dump;
1165  dump.SendDumpResponse(GetSeqNum(), req_);
1166  return;
1167  } else if (req_->get_h_op() == sandesh_op::GET) {
1168  VrfDumpHandler dump;
1169  dump.SendGetResponse(GetSeqNum(), req_->get_vrf_idx());
1170  return;
1171  } else {
1172  //store in the map
1173  vr_vrf_req vrf_info(*req_);
1174  sock->vrf_map[req_->get_vrf_idx()] = vrf_info;
1175  }
1176  KSyncSockTypeMap::SimulateResponse(GetSeqNum(), 0, 0);
1177 }
1181  new KSyncUserSockVrfContext(GetSeqNum(), req);
1182 
1183  if (sock->IsBlockMsgProcessing()) {
1184  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1185  sock->ctx_queue_.push(ctx);
1186  } else {
1187  ctx->Process();
1188  delete ctx;
1189  }
1190 }
1191 
1193  if (req_->get_h_op() == sandesh_op::DUMP) {
1194  VrfStatsDumpHandler dump;
1195  dump.SendDumpResponse(GetSeqNum(), req_);
1196  } else if (req_->get_h_op() == sandesh_op::GET) {
1197  VrfStatsDumpHandler dump;
1198  dump.SendGetResponse(GetSeqNum(), req_->get_vsr_vrf());
1199  }
1200 }
1201 
1202 void KSyncUserSockContext::VrfStatsMsgHandler(vr_vrf_stats_req *req) {
1205  GetSeqNum(), req);
1206 
1207  if (sock->IsBlockMsgProcessing()) {
1208  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1209  sock->ctx_queue_.push(vrfctx);
1210  } else {
1211  vrfctx->Process();
1212  delete vrfctx;
1213  }
1214 }
1215 
1217  if (req_->get_h_op() == sandesh_op::GET) {
1218  DropStatsDumpHandler dump;
1219  dump.SendGetResponse(GetSeqNum(), 0);
1220  }
1221 }
1222 
1223 void KSyncUserSockContext::DropStatsMsgHandler(vr_drop_stats_req *req) {
1226  GetSeqNum(), req);
1227 
1228  if (sock->IsBlockMsgProcessing()) {
1229  tbb::mutex::scoped_lock lock(sock->ctx_queue_lock_);
1230  sock->ctx_queue_.push(dropctx);
1231  } else {
1232  dropctx->Process();
1233  delete dropctx;
1234  }
1235 }
1236 
1237 void MockDumpHandlerBase::SendDumpResponse(uint32_t seq_num, Sandesh *from_req) {
1239  struct nl_client cl;
1240  int error = 0, ret;
1241  uint8_t *buf = NULL;
1242  uint32_t buf_len = 0, encode_len = 0, tot_encode_len = 0;
1243  struct nlmsghdr *nlh = NULL;
1244  bool more = false;
1245  int count = 0;
1246  unsigned int resp_code = 0;
1247 
1249  int ret_code = -KSyncSockTypeMap::error_code();
1250  ret_code &= ~VR_MESSAGE_DUMP_INCOMPLETE;
1251  KSyncSockTypeMap::SimulateResponse(seq_num, ret_code, 0);
1252  return;
1253  }
1254  Sandesh *req = GetFirst(from_req);
1255  if (req != NULL) {
1256  nl_init_generic_client_req(&cl, KSyncSock::GetNetlinkFamilyId());
1257  if ((ret = nl_build_header(&cl, &buf, &buf_len)) < 0) {
1258  LOG(DEBUG, "Error creating interface DUMP message : " << ret);
1259  nl_free(&cl);
1260  return;
1261  }
1262 
1263  nlh = (struct nlmsghdr *)cl.cl_buf;
1264  nlh->nlmsg_seq = seq_num;
1265  }
1266 
1267  while(req != NULL) {
1268  encode_len = req->WriteBinary(buf, buf_len, &error);
1269  if (error != 0) {
1270  break;
1271  }
1272  buf += encode_len;
1273  buf_len -= encode_len;
1274  tot_encode_len += encode_len;
1275  count++;
1276 
1277  req = GetNext(req);
1278  //If the remaining buffer length cannot accomodate any more encoded
1279  //messages, quit from the loop.
1280  if (req != NULL && buf_len < encode_len) {
1281  more = true;
1282  break;
1283  }
1284  }
1285 
1286  if (error) {
1287  KSyncSockTypeMap::SimulateResponse(seq_num, -ENOENT, 0);
1288  nl_free(&cl);
1289  return;
1290  }
1291 
1292  resp_code = count;
1293  if (count > 0) {
1294  resp_code = count;
1295  if (more) {
1296  resp_code = resp_code | VR_MESSAGE_DUMP_INCOMPLETE;
1297  }
1298  //Send Vr-Response (with multi-flag set)
1299  KSyncSockTypeMap::SimulateResponse(seq_num, resp_code, NLM_F_MULTI);
1300 
1301  //Send dump-response containing objects (with multi-flag set)
1302  nlh->nlmsg_flags |= NLM_F_MULTI;
1303  nl_update_header(&cl, tot_encode_len);
1304  sock->AddNetlinkTxBuff(&cl);
1305  } else {
1306  KSyncSockTypeMap::SimulateResponse(seq_num, resp_code, 0);
1307  }
1308 }
1309 
1310 void MockDumpHandlerBase::SendGetResponse(uint32_t seq_num, int idx) {
1312  struct nl_client cl;
1313  int error = 0, ret;
1314  uint8_t *buf = NULL;
1315  uint32_t buf_len = 0, encode_len = 0;
1316  struct nlmsghdr *nlh;
1317 
1318  /* To simulate error code return the test code has to call
1319  * KSyncSockTypeMap::set_error_code() with required error code and
1320  * invoke get request */
1322  int ret_code = -KSyncSockTypeMap::error_code();
1323  ret_code &= ~VR_MESSAGE_DUMP_INCOMPLETE;
1324  KSyncSockTypeMap::SimulateResponse(seq_num, ret_code, 0);
1325  return;
1326  }
1327  Sandesh *req = Get(idx);
1328  if (req == NULL) {
1329  KSyncSockTypeMap::SimulateResponse(seq_num, -ENOENT, 0);
1330  return;
1331  }
1332  nl_init_generic_client_req(&cl, KSyncSock::GetNetlinkFamilyId());
1333  if ((ret = nl_build_header(&cl, &buf, &buf_len)) < 0) {
1334  LOG(DEBUG, "Error creating interface DUMP message : " << ret);
1335  nl_free(&cl);
1336  return;
1337  }
1338 
1339  nlh = (struct nlmsghdr *)cl.cl_buf;
1340  nlh->nlmsg_seq = seq_num;
1341 
1342  int resp_len = EncodeVrResponse(buf, buf_len, seq_num, 0);
1343  buf += resp_len;
1344  buf_len -= resp_len;
1345 
1346  encode_len = req->WriteBinary(buf, buf_len, &error);
1347  if (error) {
1348  KSyncSockTypeMap::SimulateResponse(seq_num, -ENOENT, 0);
1349  nl_free(&cl);
1350  return;
1351  }
1352  buf += encode_len;
1353  buf_len -= encode_len;
1354 
1355  nl_update_header(&cl, encode_len + resp_len);
1356  sock->AddNetlinkTxBuff(&cl);
1357 }
1358 
1361  KSyncSockTypeMap::ksync_map_if::const_iterator it;
1362  static vr_interface_req req;
1363 
1364  it = sock->if_map.find(idx);
1365  if (it != sock->if_map.end()) {
1366  req = it->second;
1367  return &req;
1368  }
1369  return NULL;
1370 }
1371 
1374  KSyncSockTypeMap::ksync_map_if::const_iterator it;
1375  static vr_interface_req req;
1376  int idx;
1377  vr_interface_req *orig_req;
1378  orig_req = static_cast<vr_interface_req *>(from_req);
1379 
1380  idx = orig_req->get_vifr_marker();
1381  it = sock->if_map.upper_bound(idx);
1382 
1383  if (it != sock->if_map.end()) {
1384  req = it->second;
1385  req.set_vifr_flags(orig_req->get_vifr_flags());
1386  return &req;
1387  }
1388  return NULL;
1389 }
1390 
1392  static int last_intf_id = 0;
1393  static int32_t last_if_flags = 0;
1395  KSyncSockTypeMap::ksync_map_if::const_iterator it;
1396  static vr_interface_req req, *r;
1397 
1398  r = dynamic_cast<vr_interface_req *>(input);
1399  if (r != NULL) {
1400  /* GetNext on vr_interface_req should return a dummy drop-stats object.
1401  * We need to store the interface index which will be used during
1402  * GetNext of IfDumpHandler when invoked with vr_drop_stats_req as
1403  * argument */
1404  last_intf_id = r->get_vifr_idx();
1405  last_if_flags = r->get_vifr_flags();
1406  if (r->get_vifr_flags() & VIF_FLAG_GET_DROP_STATS) {
1407  return &drop_stats_req;
1408  }
1409  }
1410  it = sock->if_map.upper_bound(last_intf_id);
1411 
1412  if (it != sock->if_map.end()) {
1413  req = it->second;
1414  req.set_vifr_flags(last_if_flags);
1415  return &req;
1416  }
1417  return NULL;
1418 }
1419 
1422  KSyncSockTypeMap::ksync_map_nh::const_iterator it;
1423  static vr_nexthop_req req;
1424 
1425  it = sock->nh_map.find(idx);
1426  if (it != sock->nh_map.end()) {
1427  req = it->second;
1428  return &req;
1429  }
1430  return NULL;
1431 }
1432 
1435  KSyncSockTypeMap::ksync_map_nh::const_iterator it;
1436  static vr_nexthop_req req;
1437  vr_nexthop_req *orig_req;
1438  orig_req = static_cast<vr_nexthop_req *>(from_req);
1439  int idx;
1440 
1441  idx = orig_req->get_nhr_marker();
1442  it = sock->nh_map.upper_bound(idx);
1443  if (it != sock->nh_map.end()) {
1444  req = it->second;
1445  return &req;
1446  }
1447  return NULL;
1448 }
1449 
1452  KSyncSockTypeMap::ksync_map_nh::const_iterator it;
1453  static vr_nexthop_req req, *r;
1454 
1455  r = static_cast<vr_nexthop_req *>(input);
1456  it = sock->nh_map.upper_bound(r->get_nhr_id());
1457 
1458  if (it != sock->nh_map.end()) {
1459  req = it->second;
1460  return &req;
1461  }
1462  return NULL;
1463 }
1464 
1467  KSyncSockTypeMap::ksync_map_mpls::const_iterator it;
1468  static vr_mpls_req req;
1469 
1470  it = sock->mpls_map.find(idx);
1471  if (it != sock->mpls_map.end()) {
1472  req = it->second;
1473  return &req;
1474  }
1475  return NULL;
1476 }
1477 
1480  KSyncSockTypeMap::ksync_map_mpls::const_iterator it;
1481  static vr_mpls_req req;
1482  vr_mpls_req *orig_req;
1483  orig_req = static_cast<vr_mpls_req *>(from_req);
1484  int idx;
1485 
1486  idx = orig_req->get_mr_marker();
1487  it = sock->mpls_map.upper_bound(idx);
1488 
1489  if (it != sock->mpls_map.end()) {
1490  req = it->second;
1491  return &req;
1492  }
1493  return NULL;
1494 }
1495 
1498  KSyncSockTypeMap::ksync_map_mpls::const_iterator it;
1499  static vr_mpls_req req, *r;
1500 
1501  r = static_cast<vr_mpls_req *>(input);
1502  it = sock->mpls_map.upper_bound(r->get_mr_label());
1503 
1504  if (it != sock->mpls_map.end()) {
1505  req = it->second;
1506  return &req;
1507  }
1508  return NULL;
1509 }
1510 
1513  KSyncSockTypeMap::ksync_map_vrf::const_iterator it;
1514  static vr_vrf_req req;
1515 
1516  it = sock->vrf_map.find(idx);
1517  if (it != sock->vrf_map.end()) {
1518  req = it->second;
1519  return &req;
1520  }
1521  return NULL;
1522 }
1523 
1526  KSyncSockTypeMap::ksync_map_vrf::const_iterator it;
1527  static vr_vrf_req req;
1528  vr_vrf_req *orig_req;
1529  orig_req = static_cast<vr_vrf_req *>(from_req);
1530  int idx;
1531 
1532  idx = orig_req->get_vrf_marker();
1533  it = sock->vrf_map.upper_bound(idx);
1534 
1535  if (it != sock->vrf_map.end()) {
1536  req = it->second;
1537  return &req;
1538  }
1539  return NULL;
1540 }
1541 
1544  KSyncSockTypeMap::ksync_map_vrf::const_iterator it;
1545  static vr_vrf_req req, *r;
1546 
1547  r = static_cast<vr_vrf_req *>(input);
1548  it = sock->vrf_map.upper_bound(r->get_vrf_idx());
1549 
1550  if (it != sock->vrf_map.end()) {
1551  req = it->second;
1552  return &req;
1553  }
1554  return NULL;
1555 }
1556 
1559  KSyncSockTypeMap::ksync_map_mirror::const_iterator it;
1560  static vr_mirror_req req;
1561 
1562  it = sock->mirror_map.find(idx);
1563  if (it != sock->mirror_map.end()) {
1564  req = it->second;
1565  return &req;
1566  }
1567  return NULL;
1568 }
1569 
1572  KSyncSockTypeMap::ksync_map_mirror::const_iterator it;
1573  static vr_mirror_req req;
1574  vr_mirror_req *orig_req;
1575  orig_req = static_cast<vr_mirror_req *>(from_req);
1576  int idx;
1577 
1578  idx = orig_req->get_mirr_marker();
1579  it = sock->mirror_map.upper_bound(idx);
1580 
1581  if (it != sock->mirror_map.end()) {
1582  req = it->second;
1583  return &req;
1584  }
1585  return NULL;
1586 }
1587 
1590  KSyncSockTypeMap::ksync_map_mirror::const_iterator it;
1591  static vr_mirror_req req, *r;
1592 
1593  r = static_cast<vr_mirror_req *>(input);
1594  it = sock->mirror_map.upper_bound(r->get_mirr_index());
1595 
1596  if (it != sock->mirror_map.end()) {
1597  req = it->second;
1598  return &req;
1599  }
1600  return NULL;
1601 }
1602 
1605  KSyncSockTypeMap::ksync_rt_tree::const_iterator it;
1606  static vr_route_req req;
1607  vr_route_req *orig_req, key;
1608  orig_req = static_cast<vr_route_req *>(from_req);
1609 
1610  key.set_rtr_family(orig_req->get_rtr_family());
1611  key.set_rtr_vrf_id(orig_req->get_rtr_vrf_id());
1612  if (orig_req->get_rtr_marker().size() || orig_req->get_rtr_mac().size()) {
1613  if (orig_req->get_rtr_family() == AF_BRIDGE) {
1614  key.set_rtr_mac(orig_req->get_rtr_mac());
1615  } else {
1616  key.set_rtr_prefix(orig_req->get_rtr_marker());
1617  key.set_rtr_prefix_len(orig_req->get_rtr_marker_plen());
1618  }
1619  it = sock->rt_tree.upper_bound(key);
1620  } else {
1621  std::vector<int8_t> rtr_prefix;
1622  if (orig_req->get_rtr_family() == AF_BRIDGE) {
1623  key.set_rtr_mac(rtr_prefix);
1624  } else {
1625  key.set_rtr_prefix(rtr_prefix);
1626  key.set_rtr_prefix_len(0);
1627  }
1628  it = sock->rt_tree.lower_bound(key);
1629  }
1630 
1631 
1632  if (it != sock->rt_tree.end()) {
1633  if ((it->get_rtr_vrf_id() != orig_req->get_rtr_vrf_id()) ||
1634  (it->get_rtr_family() != orig_req->get_rtr_family())) {
1635  return NULL;
1636  }
1637  req = *it;
1638  return &req;
1639  }
1640  return NULL;
1641 }
1642 
1645  KSyncSockTypeMap::ksync_rt_tree::const_iterator it;
1646  static vr_route_req req, *r, key;
1647 
1648  r = static_cast<vr_route_req *>(input);
1649 
1650  key.set_rtr_vrf_id(r->get_rtr_vrf_id());
1651  key.set_rtr_family(r->get_rtr_family());
1652  if (r->get_rtr_family() == AF_BRIDGE) {
1653  key.set_rtr_mac(r->get_rtr_mac());
1654  } else {
1655  key.set_rtr_prefix(r->get_rtr_prefix());
1656  key.set_rtr_prefix_len(r->get_rtr_prefix_len());
1657  }
1658  it = sock->rt_tree.upper_bound(key);
1659 
1660  if (it != sock->rt_tree.end()) {
1661  if ((it->get_rtr_vrf_id() != r->get_rtr_vrf_id()) ||
1662  (it->get_rtr_family() != r->get_rtr_family())) {
1663  return NULL;
1664  }
1665  req = *it;
1666  return &req;
1667  }
1668  return NULL;
1669 }
1670 
1673  KSyncSockTypeMap::ksync_vrf_assign_tree::const_iterator it;
1674  static vr_vrf_assign_req req;
1675  vr_vrf_assign_req *orig_req, key;
1676  orig_req = static_cast<vr_vrf_assign_req *>(from_req);
1677 
1678  key.set_var_vif_index(orig_req->get_var_vif_index());
1679  key.set_var_vlan_id(orig_req->get_var_marker());
1680  it = sock->vrf_assign_tree.upper_bound(key);
1681 
1682  if (it != sock->vrf_assign_tree.end()) {
1683  req = *it;
1684  return &req;
1685  }
1686  return NULL;
1687 }
1688 
1691  KSyncSockTypeMap::ksync_vrf_assign_tree::const_iterator it;
1692  static vr_vrf_assign_req req, *r, key;
1693 
1694  r = static_cast<vr_vrf_assign_req *>(input);
1695 
1696  key.set_var_vif_index(r->get_var_vif_index());
1697  key.set_var_vlan_id(r->get_var_vlan_id());
1698  it = sock->vrf_assign_tree.upper_bound(key);
1699 
1700  if (it != sock->vrf_assign_tree.end()) {
1701  req = *it;
1702  return &req;
1703  }
1704  return NULL;
1705 }
1706 
1709  KSyncSockTypeMap::ksync_map_vrf_stats::const_iterator it;
1710  static vr_vrf_stats_req req;
1711 
1712  it = sock->vrf_stats_map.find(idx);
1713  if (it != sock->vrf_stats_map.end()) {
1714  req = it->second;
1715  return &req;
1716  }
1717  return NULL;
1718 }
1719 
1722  KSyncSockTypeMap::ksync_map_vrf_stats::const_iterator it;
1723  static vr_vrf_stats_req req;
1724  int idx;
1725  vr_vrf_stats_req *orig_req;
1726  orig_req = static_cast<vr_vrf_stats_req *>(from_req);
1727 
1728  idx = orig_req->get_vsr_marker();
1729  it = sock->vrf_stats_map.upper_bound(idx);
1730 
1731  if (it != sock->vrf_stats_map.end()) {
1732  req = it->second;
1733  return &req;
1734  }
1735  return NULL;
1736 }
1737 
1740  KSyncSockTypeMap::ksync_map_vrf_stats::const_iterator it;
1741  static vr_vrf_stats_req req, *r;
1742 
1743  r = static_cast<vr_vrf_stats_req *>(input);
1744  it = sock->vrf_stats_map.upper_bound(r->get_vsr_vrf());
1745 
1746  if (it != sock->vrf_stats_map.end()) {
1747  req = it->second;
1748  return &req;
1749  }
1750  return NULL;
1751 }
1752 
1755  KSyncSockTypeMap::ksync_map_vxlan::const_iterator it;
1756  static vr_vxlan_req req;
1757 
1758  it = sock->vxlan_map.find(idx);
1759  if (it != sock->vxlan_map.end()) {
1760  req = it->second;
1761  return &req;
1762  }
1763  return NULL;
1764 }
1765 
1768  KSyncSockTypeMap::ksync_map_vxlan::const_iterator it;
1769  static vr_vxlan_req req;
1770  vr_vxlan_req *orig_req;
1771  orig_req = static_cast<vr_vxlan_req *>(from_req);
1772  int idx;
1773 
1774  idx = orig_req->get_vxlanr_vnid();
1775  it = sock->vxlan_map.upper_bound(idx);
1776 
1777  if (it != sock->vxlan_map.end()) {
1778  req = it->second;
1779  return &req;
1780  }
1781  return NULL;
1782 }
1783 
1786  KSyncSockTypeMap::ksync_map_vxlan::const_iterator it;
1787  static vr_vxlan_req req, *r;
1788 
1789  r = static_cast<vr_vxlan_req *>(input);
1790  it = sock->vxlan_map.upper_bound(r->get_vxlanr_vnid());
1791 
1792  if (it != sock->vxlan_map.end()) {
1793  req = it->second;
1794  return &req;
1795  }
1796  return NULL;
1797 }
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:393
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
static int IoVectorToData(char *data, uint32_t len, KSyncBufferList *iovec)
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 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:328
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)