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