+static inline void dump_l3(struct task_base *tbase, struct rte_mbuf *mbuf)
+{
+ if (unlikely(tbase->aux->task_rt_dump.n_print_rx)) {
+ if ((tbase->aux->task_rt_dump.input == NULL) || (tbase->aux->task_rt_dump.input->reply == NULL)) {
+ plogdx_info(mbuf, "RX: ");
+ } else {
+ struct input *input = tbase->aux->task_rt_dump.input;
+ char tmp[128];
+ int strlen;
+#if RTE_VERSION >= RTE_VERSION_NUM(1,8,0,0)
+ int port_id = mbuf->port;
+#else
+ int port_id = mbuf->pkt.in_port;
+#endif
+ strlen = snprintf(tmp, sizeof(tmp), "pktdump,%d,%d\n", port_id,
+ rte_pktmbuf_pkt_len(mbuf));
+ input->reply(input, tmp, strlen);
+ input->reply(input, rte_pktmbuf_mtod(mbuf, char *), rte_pktmbuf_pkt_len(mbuf));
+ input->reply(input, "\n", 1);
+ }
+ tbase->aux->task_rt_dump.n_print_rx --;
+ if (0 == tbase->aux->task_rt_dump.n_print_rx) {
+ task_base_del_rx_pkt_function(tbase, rx_pkt_dump);
+ }
+ }
+ if (unlikely(tbase->aux->task_rt_dump.n_trace)) {
+ plogdx_info(mbuf, "RX: ");
+ tbase->aux->task_rt_dump.n_trace--;
+ }
+}
+
+static inline void handle_ipv4(struct task_base *tbase, struct rte_mbuf **mbufs, int i, prox_rte_ipv4_hdr *pip, int *skip)
+{
+ prox_rte_tcp_hdr *tcp = (prox_rte_tcp_hdr *)(pip + 1);
+ if (pip->next_proto_id == IPPROTO_ICMP) {
+ dump_l3(tbase, mbufs[i]);
+ tx_ring(tbase, tbase->l3.ctrl_plane_ring, ICMP_TO_MASTER, mbufs[i]);
+ (*skip)++;
+ } else if ((tcp->src_port == TCP_PORT_BGP) || (tcp->dst_port == TCP_PORT_BGP)) {
+ dump_l3(tbase, mbufs[i]);
+ tx_ring(tbase, tbase->l3.ctrl_plane_ring, BGP_TO_MASTER, mbufs[i]);
+ (*skip)++;
+ } else if (unlikely(*skip)) {
+ mbufs[i - *skip] = mbufs[i];
+ }
+}
+static inline int handle_l3(struct task_base *tbase, uint16_t nb_rx, struct rte_mbuf ***mbufs_ptr)
+{
+ struct rte_mbuf **mbufs = *mbufs_ptr;
+ int i;
+ struct ether_hdr_arp *hdr_arp[MAX_PKT_BURST];
+ prox_rte_ether_hdr *hdr;
+ prox_rte_ipv4_hdr *pip;
+ prox_rte_vlan_hdr *vlan;
+ int skip = 0;
+
+ for (i = 0; i < nb_rx; i++) {
+ PREFETCH0(mbufs[i]);
+ }
+
+ for (i = 0; i < nb_rx; i++) {
+ hdr_arp[i] = rte_pktmbuf_mtod(mbufs[i], struct ether_hdr_arp *);
+ PREFETCH0(hdr_arp[i]);
+ }
+ for (i = 0; i < nb_rx; i++) {
+ if (likely(hdr_arp[i]->ether_hdr.ether_type == ETYPE_IPv4)) {
+ hdr = (prox_rte_ether_hdr *)hdr_arp[i];
+ pip = (prox_rte_ipv4_hdr *)(hdr + 1);
+ handle_ipv4(tbase, mbufs, i, pip, &skip);
+ } else {
+ switch (hdr_arp[i]->ether_hdr.ether_type) {
+ case ETYPE_VLAN:
+ hdr = (prox_rte_ether_hdr *)hdr_arp[i];
+ vlan = (prox_rte_vlan_hdr *)(hdr + 1);
+ if (vlan->eth_proto == ETYPE_IPv4) {
+ pip = (prox_rte_ipv4_hdr *)(vlan + 1);
+ handle_ipv4(tbase, mbufs, i, pip, &skip);
+ } else if (vlan->eth_proto == ETYPE_ARP) {
+ dump_l3(tbase, mbufs[i]);
+ tx_ring(tbase, tbase->l3.ctrl_plane_ring, ARP_PKT_FROM_NET_TO_MASTER, mbufs[i]);
+ skip++;
+ }
+ break;
+ case ETYPE_ARP:
+ dump_l3(tbase, mbufs[i]);
+ tx_ring(tbase, tbase->l3.ctrl_plane_ring, ARP_PKT_FROM_NET_TO_MASTER, mbufs[i]);
+ skip++;
+ break;
+ default:
+ if (unlikely(skip)) {
+ mbufs[i - skip] = mbufs[i];
+ }
+ }
+ }
+ }
+ return skip;
+}
+
+static inline int handle_ndp(struct task_base *tbase, uint16_t nb_rx, struct rte_mbuf ***mbufs_ptr)
+{
+ struct rte_mbuf **mbufs = *mbufs_ptr;
+ prox_rte_ipv6_hdr *ipv6_hdr;
+ int i;
+ prox_rte_ether_hdr *hdr[MAX_PKT_BURST];
+ int skip = 0;
+ uint16_t vlan = 0;
+
+ for (i = 0; i < nb_rx; i++) {
+ PREFETCH0(mbufs[i]);
+ }
+ for (i = 0; i < nb_rx; i++) {
+ hdr[i] = rte_pktmbuf_mtod(mbufs[i], prox_rte_ether_hdr *);
+ PREFETCH0(hdr[i]);
+ }
+ for (i = 0; i < nb_rx; i++) {
+ ipv6_hdr = prox_get_ipv6_hdr(hdr[i], rte_pktmbuf_pkt_len(mbufs[i]), &vlan);
+ if (unlikely((ipv6_hdr) && (ipv6_hdr->proto == ICMPv6))) {
+ dump_l3(tbase, mbufs[i]);
+ tx_ring(tbase, tbase->l3.ctrl_plane_ring, NDP_PKT_FROM_NET_TO_MASTER, mbufs[i]);
+ skip++;
+ } else if (unlikely(skip)) {
+ mbufs[i - skip] = mbufs[i];
+ }
+ }
+ return skip;
+}
+
+static uint16_t rx_pkt_hw_param(struct task_base *tbase, struct rte_mbuf ***mbufs_ptr, int multi,
+ void (*next)(struct rx_params_hw *rx_param_hw), int l3_ndp)