OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bfd_handler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <cmn/agent_cmn.h>
6 #include <init/agent_init.h>
7 #include <pkt/pkt_init.h>
8 #include <pkt/pkt_handler.h>
9 #include <services/bfd_proto.h>
11 
12 BfdHandler::BfdHandler(Agent *agent, boost::shared_ptr<PktInfo> info,
13  boost::asio::io_context &io)
14  : ProtoHandler(agent, info, io) {
15 }
16 
18 }
19 
21  BfdProto *bfd_proto = agent()->GetBfdProto();
22  uint8_t len = ntohs(pkt_info_->transp.udp->len) - 8;
23  uint8_t *data = new uint8_t[len];
24  memcpy(data, pkt_info_->data, len);
25  boost::asio::const_buffer buffer(boost::asio::buffer(data, len));
26 
27  boost::system::error_code ec;
28  boost::asio::ip::udp::endpoint local_endpoint(pkt_info_->ip_daddr,
29  pkt_info_->dport);
30  boost::asio::ip::udp::endpoint remote_endpoint(pkt_info_->ip_saddr,
31  pkt_info_->sport);
32  // thread safe!
33  bfd_proto->HandleReceiveSafe(
34  buffer, local_endpoint, remote_endpoint,
36  len, ec);
37  return true;
38 }
39 
41  Interface *itf =
43  if (itf == NULL) {
44  return true;
45  }
46 
47  return HandleReceive();
48 }
49 
51  const boost::asio::ip::udp::endpoint &local_endpoint,
52  const boost::asio::ip::udp::endpoint &remote_endpoint,
53  uint32_t interface_id, const boost::asio::mutable_buffer &packet,
54  int packet_length) {
55 
56  Interface *intrface =
57  agent()->interface_table()->FindInterface(interface_id);
58  if (!intrface || intrface->type() != Interface::VM_INTERFACE)
59  return;
60 
61  if (pkt_info_->packet_buffer() == NULL) {
62  pkt_info_->AllocPacketBuffer(agent(), PktHandler::BFD,
63  BFD_TX_BUFF_LEN, 0);
64  }
65 
66  uint16_t buf_len = pkt_info_->packet_buffer()->data_len();
67  char *ptr = (char *)pkt_info_->packet_buffer()->data();
68  memset(ptr, 0, buf_len);
69  pkt_info_->eth = (struct ether_header *)ptr;
70 
71  VmInterface *vm_interface = static_cast<VmInterface *>(intrface);
72  bool is_v4 = local_endpoint.address().is_v4();
73  uint16_t len = 0;
74 
75  uint8_t *data = boost::asio::buffer_cast<uint8_t *>(packet);
76  uint16_t eth_proto = is_v4 ? ETHERTYPE_IP : ETHERTYPE_IPV6;
78  GetMacIpLearningTable()->GetPairedMacAddress(
79  vm_interface->vrf()?
80  vm_interface->vrf()->vrf_id():
82  remote_endpoint.address());
83 
84  if (mac == MacAddress()) {
85  mac = vm_interface->vm_mac();
86  }
87 
88  len += EthHdr(ptr + len, buf_len - len,
89  agent()->vrrp_mac(),
90  mac,
91  eth_proto, vm_interface->tx_vlan_id());
92 
93  if (is_v4) {
94  uint16_t ip_len = sizeof(struct ip) + sizeof(udphdr) + packet_length;
95  len += IpHdr(ptr + len, buf_len - len, ip_len,
96  htonl(local_endpoint.address().to_v4().to_ulong()),
97  htonl(remote_endpoint.address().to_v4().to_ulong()),
98  IPPROTO_UDP, 0, 255);
99  memcpy(ptr + len + sizeof(udphdr), data, packet_length);
100  len += UdpHdr((udphdr *)(ptr + len), buf_len - len,
101  sizeof(udphdr) + packet_length,
102  htonl(local_endpoint.address().to_v4().to_ulong()),
103  local_endpoint.port(),
104  htonl(remote_endpoint.address().to_v4().to_ulong()),
105  remote_endpoint.port());
106  } else {
107  pkt_info_->ip6 = (struct ip6_hdr *)(ptr + len);
108  Ip6Hdr((ip6_hdr *)(ptr + len),
109  sizeof(udphdr) + packet_length,
110  IPPROTO_UDP, 64,
111  local_endpoint.address().to_v6().to_bytes().data(),
112  remote_endpoint.address().to_v6().to_bytes().data());
113  len += sizeof(ip6_hdr);
114  memcpy(ptr + len + sizeof(udphdr), data, packet_length);
115  pkt_info_->transp.udp = (struct udphdr *)(ptr + len);
116  UdpHdr((udphdr *)(ptr + len), sizeof(udphdr) + packet_length,
117  local_endpoint.address().to_v6().to_bytes().data(),
118  local_endpoint.port(),
119  remote_endpoint.address().to_v6().to_bytes().data(),
120  remote_endpoint.port(), IPPROTO_UDP);
121  len += sizeof(udphdr);
122  }
123 
124  len += packet_length;
125 
126  pkt_info_->set_len(len);
127  Send(interface_id, vm_interface->vrf_id(),
129  pkt_info_->reset_packet_buffer();
130  const uint8_t *p = boost::asio::buffer_cast<const uint8_t *>(packet);
131  delete[] p;
132 }
const MacAddress & vm_mac() const
Type type() const
Definition: interface.h:112
MacLearningProto * mac_learning_proto() const
Definition: agent.h:1005
InterfaceTable * interface_table() const
Definition: agent.h:465
#define BFD_TX_BUFF_LEN
Definition: bfd_proto.h:20
virtual ~BfdHandler()
Definition: bfd_handler.cc:17
VrfEntry * vrf() const
Definition: interface.h:115
Agent * agent() const
Definition: proto_handler.h:80
boost::shared_ptr< PktInfo > pkt_info_
Definition: proto_handler.h:92
uint16_t tx_vlan_id() const
int EthHdr(const MacAddress &src, const MacAddress &dest, const uint16_t proto)
BfdProto * GetBfdProto() const
Definition: agent.h:990
void HandleReceiveSafe(boost::asio::const_buffer pkt, const boost::asio::ip::udp::endpoint &local_endpoint, const boost::asio::ip::udp::endpoint &remote_endpoint, const BFD::SessionIndex &session_index, uint8_t pkt_len, boost::system::error_code ec)
Definition: bfd_proto.cc:204
Definition: agent.h:358
uint32_t GetInterfaceIndex() const
Definition: proto_handler.h:82
uint32_t vrf_id() const
Definition: interface.cc:621
bool Run()
Definition: bfd_handler.cc:40
void Send(uint32_t itf, uint32_t vrf, uint16_t, PktHandler::PktModuleName)
BfdHandler(Agent *agent, boost::shared_ptr< PktInfo > info, boost::asio::io_context &io)
Definition: bfd_handler.cc:12
bool HandleReceive()
Definition: bfd_handler.cc:20
const uint32_t vrf_id() const
Definition: vrf.h:99
void Ip6Hdr(ip6_hdr *ip, uint16_t plen, uint8_t next_header, uint8_t hlim, uint8_t *src, uint8_t *dest)
void UdpHdr(uint16_t len, in_addr_t src, uint16_t src_port, in_addr_t dest, uint16_t dest_port)
const Interface * FindInterface(size_t index) const
Definition: interface.cc:323
static const uint32_t kInvalidIndex
Definition: vrf.h:88
void SendPacket(const boost::asio::ip::udp::endpoint &local_endpoint, const boost::asio::ip::udp::endpoint &remote_endpoint, uint32_t interface_id, const boost::asio::mutable_buffer &packet, int packet_length)
Definition: bfd_handler.cc:50
void IpHdr(uint16_t len, in_addr_t src, in_addr_t dest, uint8_t protocol, uint16_t id, uint8_t ttl)