diff --git a/dp-core/vr_interface.c b/dp-core/vr_interface.c index 95e460f38..8dc8ad41e 100644 --- a/dp-core/vr_interface.c +++ b/dp-core/vr_interface.c @@ -231,10 +231,6 @@ vif_xconnect(struct vr_interface *vif, struct vr_packet *pkt, return 0; } -/* agent driver */ -#define AGENT_PKT_HEAD_SPACE (sizeof(struct vr_eth) + \ - sizeof(struct agent_hdr)) - static unsigned char * agent_set_rewrite(struct vr_interface *vif, struct vr_packet *pkt, struct vr_forwarding_md *fmd, unsigned char *rewrite, diff --git a/dp-core/vr_nexthop.c b/dp-core/vr_nexthop.c index dea8f13fc..960ec33b2 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -773,13 +773,18 @@ nh_handle_mcast_control_pkt(struct vr_packet *pkt, struct vr_forwarding_md *fmd, unsigned int pkt_src, bool *flood_to_vms) { int handled = 1; + bool flood = false; unsigned short trap, rt_flags, drop_reason, pull_len = 0; + l4_pkt_type_t l4_type = L4_TYPE_UNKNOWN; + struct vr_eth *eth; struct vr_arp *sarp; struct vr_nexthop *src_nh; struct vr_ip6 *ip6; + struct vr_packet *pkt_c = NULL; + /* * The vlan tagged packets are meant to be handled only by VM's */ @@ -836,7 +841,7 @@ nh_handle_mcast_control_pkt(struct vr_packet *pkt, struct vr_forwarding_md *fmd, /* * If packet is identified as known packet, we always trap - * it to Agentm with the exception of DHCP. DHCP can be flooded + * it to agent with the exception of DHCP. DHCP can be flooded * depending on the configuration on VMI or L2 route flags */ if (l4_type != L4_TYPE_UNKNOWN) { @@ -849,12 +854,27 @@ nh_handle_mcast_control_pkt(struct vr_packet *pkt, struct vr_forwarding_md *fmd, trap = false; } else if (l4_type == L4_TYPE_NEIGHBOUR_SOLICITATION) { trap = false; + } else if (l4_type == L4_TYPE_NEIGHBOUR_ADVERTISEMENT) { + flood = true; } + if (trap && flood) { + pkt_c = nh_mcast_clone(pkt, AGENT_PKT_HEAD_SPACE); + if (!pkt_c) { + trap = false; + } + } if (trap) { - vr_trap(pkt, fmd->fmd_dvrf, AGENT_TRAP_L3_PROTOCOLS, NULL); - return handled; + if (flood) { + vr_trap(pkt_c, fmd->fmd_dvrf, + AGENT_TRAP_L3_PROTOCOLS, NULL); + goto unhandled; + } else { + vr_trap(pkt, fmd->fmd_dvrf, + AGENT_TRAP_L3_PROTOCOLS, NULL); + return handled; + } } } } diff --git a/dp-core/vr_proto_ip6.c b/dp-core/vr_proto_ip6.c index 49df82409..d3bf4934d 100644 --- a/dp-core/vr_proto_ip6.c +++ b/dp-core/vr_proto_ip6.c @@ -569,6 +569,8 @@ vr_ip6_well_known_packet(struct vr_packet *pkt) return L4_TYPE_ROUTER_SOLICITATION; if (icmph && (icmph->icmp_type == VR_ICMP6_TYPE_NEIGH_SOL)) return L4_TYPE_NEIGHBOUR_SOLICITATION; + if (icmph && (icmph->icmp_type == VR_ICMP6_TYPE_NEIGH_AD)) + return L4_TYPE_NEIGHBOUR_ADVERTISEMENT; } if (ip6->ip6_nxt == VR_IP_PROTO_UDP) { diff --git a/include/vr_defs.h b/include/vr_defs.h index df8d3859e..4c0ade988 100644 --- a/include/vr_defs.h +++ b/include/vr_defs.h @@ -55,6 +55,9 @@ enum rt_type{ #define VR_BE_LABEL_VALID_FLAG 0x02 #define VR_BE_FLOOD_DHCP_FLAG 0x04 +#define AGENT_PKT_HEAD_SPACE (sizeof(struct vr_eth) + \ + sizeof(struct agent_hdr)) + struct agent_hdr { unsigned short hdr_ifindex; unsigned short hdr_vrf; diff --git a/include/vr_packet.h b/include/vr_packet.h index 3dbd11da7..de064ca60 100644 --- a/include/vr_packet.h +++ b/include/vr_packet.h @@ -273,6 +273,7 @@ typedef enum { L4_TYPE_DHCP_REQUEST, L4_TYPE_ROUTER_SOLICITATION, L4_TYPE_NEIGHBOUR_SOLICITATION, + L4_TYPE_NEIGHBOUR_ADVERTISEMENT, } l4_pkt_type_t; struct vr_eth {