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;