OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
icmpv6_error_handler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 #include "base/os.h"
5 #include <netinet/icmp6.h>
6 #include <vr_defs.h>
7 #include <cmn/agent_cmn.h>
9 #include <oper/vn.h>
10 #include <pkt/pkt_init.h>
14 #include <services/services_init.h>
15 #include <services/icmpv6_proto.h>
16 
17 
19 
21  boost::shared_ptr<PktInfo> info,
22  boost::asio::io_context *io) :
23  ProtoHandler(agent, info, *io), proto_(proto) {
24 }
25 
27 }
28 
30  if (pkt_info_->len < (sizeof(struct ether_header) + sizeof(struct ip6_hdr)))
31  return false;
32  return true;
33 }
34 
36 
37  if (ValidatePacket() == false) {
39  return true;
40  }
41 
42  VmInterface *vm_itf = dynamic_cast<VmInterface *>
44  if (vm_itf == NULL || vm_itf->layer3_forwarding() == false ||
45  vm_itf->IsActive() == false) {
47  return true;
48  }
49  return SendIcmpv6Error(vm_itf);
50 }
51 
52 // Generate ICMP error
54 
55  char *buff = (char *)pkt_info_->pkt;
56  uint16_t buff_len = pkt_info_->packet_buffer()->data_len();
57  char data[ICMPV6_PAYLOAD_LEN];
58  int len = ntohs(pkt_info_->ip6->ip6_plen);
59 
60  if (len > ICMPV6_PAYLOAD_LEN)
61  len = ICMPV6_PAYLOAD_LEN;
62 
63  memcpy(data, pkt_info_->ip6, len);
64 
65  Ip6Address source_address;
66  boost::system::error_code ec;
67  const VnIpam *ipam = intf->vn()->GetIpam(pkt_info_->ip_saddr.to_v6());
68  if (ipam != NULL) {
69  if (ipam->default_gw.is_v6())
70  source_address = ipam->default_gw.to_v6();
71  }
72  // If source address is not found, use vhost address mapped v6 address.
73  // vrouter forwards the icmp error packets as part of the original flow.
74  if (source_address.is_unspecified())
75  source_address = Ip6Address::v4_mapped(agent()->router_id());
76 
77  uint32_t interface =
78  (pkt_info_->agent_hdr.cmd == AgentHdr::TRAP_TOR_CONTROL_PKT) ?
79  pkt_info_->agent_hdr.cmd_param : GetInterfaceIndex();
80 
81  uint16_t eth_len = EthHdr(buff, buff_len, interface,
82  agent()->vhost_interface()->mac(),
83  MacAddress(pkt_info_->eth->ether_shost),
84  ETHERTYPE_IPV6);
85 
86  pkt_info_->ip6 = (struct ip6_hdr *)(buff + eth_len);
88  255, source_address.to_bytes().data(),
89  pkt_info_->ip_saddr.to_v6().to_bytes().data());
90 
91  icmp6_hdr *icmp = pkt_info_->transp.icmp6 =
92  (icmp6_hdr *)(pkt_info_->pkt + eth_len
93  + sizeof(ip6_hdr));
94  icmp->icmp6_type = ICMP6_PACKET_TOO_BIG;
95  icmp->icmp6_code = 0;
96  icmp->icmp6_mtu = htonl(pkt_info_->agent_hdr.mtu);
97  icmp->icmp6_cksum = 0;
98  memcpy(buff + sizeof(ip6_hdr) + eth_len+ICMP_UNREACH_HDR_LEN, data, len);
99  icmp->icmp6_cksum =
100  Icmpv6Csum(source_address.to_bytes().data(),
101  pkt_info_->ip_saddr.to_v6().to_bytes().data(),
102  icmp, len + ICMP_UNREACH_HDR_LEN);
103  pkt_info_->set_len(len + sizeof(ip6_hdr) + eth_len+ICMP_UNREACH_HDR_LEN);
104 
105  uint16_t command =
106  (pkt_info_->agent_hdr.cmd == AgentHdr::TRAP_TOR_CONTROL_PKT) ?
108 
109  Send(GetInterfaceIndex(), pkt_info_->vrf, command,
111  return true;
112 }
bool SendIcmpv6Error(VmInterface *intf)
const VnIpam * GetIpam(const IpAddress &ip) const
Definition: vn.cc:651
Definition: vn.h:28
InterfaceTable * interface_table() const
Definition: agent.h:465
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
Agent * agent() const
Definition: proto_handler.h:80
void increment_interface_errors()
boost::shared_ptr< PktInfo > pkt_info_
Definition: proto_handler.h:92
int EthHdr(const MacAddress &src, const MacAddress &dest, const uint16_t proto)
bool IsActive() const
IpAddress default_gw
Definition: vn.h:31
Definition: agent.h:358
uint32_t GetInterfaceIndex() const
Definition: proto_handler.h:82
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
Ip4Address router_id() const
Definition: agent.h:666
void Send(uint32_t itf, uint32_t vrf, uint16_t, PktHandler::PktModuleName)
bool layer3_forwarding() const
const VnEntry * vn() const
void Ip6Hdr(ip6_hdr *ip, uint16_t plen, uint8_t next_header, uint8_t hlim, uint8_t *src, uint8_t *dest)
Icmpv6ErrorProto * proto_
#define ICMP_UNREACH_HDR_LEN
Definition: pkt_handler.h:51
static const int ICMPV6_PAYLOAD_LEN
Icmpv6ErrorHandler(Agent *agent, Icmpv6ErrorProto *proto, boost::shared_ptr< PktInfo > info, boost::asio::io_context *io)
const Interface * FindInterface(size_t index) const
Definition: interface.cc:323
#define IPV6_ICMP_NEXT_HEADER
uint16_t Icmpv6Csum(const uint8_t *src, const uint8_t *dest, icmp6_hdr *icmp, uint16_t plen) const
SandeshTraceBufferPtr Icmpv6TraceBuf