From 4e91f850524b67c5dc38dcf762ba584103a981cf Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Sat, 12 Mar 2016 09:53:33 +0530 Subject: [PATCH] Drop ICMP error packets for ICMP errors In case of ICMP error packets for ICMP errors, we were not initializing flow key and trying to form a flow out of that key, resulting in wrong key length and corrupted flow entry(s). We will drop such packets. Change-Id: Idae46a7e128482ad89da8b5bd1bd0ef6b17ef28e Closes-BUG: #1556363 --- dp-core/vr_proto_ip.c | 16 +++++++++++++--- dp-core/vr_proto_ip6.c | 18 ++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/dp-core/vr_proto_ip.c b/dp-core/vr_proto_ip.c index fbcf6a9d0..717cb414c 100644 --- a/dp-core/vr_proto_ip.c +++ b/dp-core/vr_proto_ip.c @@ -838,6 +838,8 @@ vr_inet_proto_flow(struct vrouter *router, unsigned short vrf, struct vr_packet *pkt, uint16_t vlan, struct vr_ip *ip, struct vr_flow *flow_p) { + int ret = 0; + unsigned short *t_hdr, sport, dport; unsigned short nh_id; @@ -849,13 +851,21 @@ vr_inet_proto_flow(struct vrouter *router, unsigned short vrf, if (ip->ip_proto == VR_IP_PROTO_ICMP) { icmph = (struct vr_icmp *)t_hdr; if (vr_icmp_error(icmph)) { + /* we will generate a flow only for the first icmp error */ if ((unsigned char *)ip == pkt_network_header(pkt)) { - vr_inet_proto_flow(router, vrf, pkt, vlan, + ret = vr_inet_proto_flow(router, vrf, pkt, vlan, (struct vr_ip *)(icmph + 1), flow_p); + if (ret) + return ret; + vr_inet_flow_swap(flow_p); + } else { + /* for icmp error for icmp error, we will drop the packet */ + return -1; } - return 0; + sport = flow_p->flow4_sport; + dport = flow_p->flow4_dport; } else if (vr_icmp_echo(icmph)) { sport = icmph->icmp_eid; dport = VR_ICMP_TYPE_ECHO_REPLY; @@ -983,7 +993,7 @@ vr_inet_flow_lookup(struct vrouter *router, struct vr_packet *pkt, vr_enqueue_to_assembler(router, pkt, fmd); } else { /* unlikely to be hit. you can safely discount misc drops here */ - vr_pfree(pkt, VP_DROP_FRAGMENTS); + vr_pfree(pkt, VP_DROP_MISC); } return FLOW_CONSUMED; } diff --git a/dp-core/vr_proto_ip6.c b/dp-core/vr_proto_ip6.c index 47a8d872f..6233c92d0 100644 --- a/dp-core/vr_proto_ip6.c +++ b/dp-core/vr_proto_ip6.c @@ -173,6 +173,7 @@ vr_inet6_form_flow(struct vrouter *router, unsigned short vrf, struct vr_packet *pkt, uint16_t vlan, struct vr_ip6 *ip6, struct vr_flow *flow_p) { + int ret = 0; unsigned short *t_hdr, sport, dport; unsigned short nh_id; @@ -183,10 +184,19 @@ vr_inet6_form_flow(struct vrouter *router, unsigned short vrf, if (ip6->ip6_nxt == VR_IP_PROTO_ICMP6) { icmph = (struct vr_icmp *)t_hdr; if (vr_icmp6_error(icmph)) { - vr_inet6_form_flow(router, vrf, pkt, vlan, - (struct vr_ip6 *)(icmph + 1), flow_p); - vr_inet6_flow_swap(flow_p); - return 0; + if ((unsigned char *)ip6 == pkt_network_header(pkt)) { + ret = vr_inet6_form_flow(router, vrf, pkt, vlan, + (struct vr_ip6 *)(icmph + 1), flow_p); + if (ret) + return ret; + + vr_inet6_flow_swap(flow_p); + } else { + return -1; + } + + sport = flow_p->flow6_sport; + dport = flow_p->flow6_dport; } else if ((icmph->icmp_type == VR_ICMP6_TYPE_ECHO_REQ) || (icmph->icmp_type == VR_ICMP6_TYPE_ECHO_REPLY)) { sport = icmph->icmp_eid;