From 7cb21a2b2b42c52a61babf3e6bc35da31922f88b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fengbojiang=28=E5=A7=9C=E5=87=A4=E6=B3=A2=29?= Date: Wed, 17 Jul 2019 17:31:47 +0800 Subject: [PATCH] IPv6: support multi-processes, deep copy NDP packet and dispatch. --- lib/Makefile | 4 ++++ lib/ff_dpdk_if.c | 19 +++++++++++++------ lib/ff_dpdk_kni.c | 30 ++++++++++++++++++++++++++++++ lib/ff_dpdk_kni.h | 5 +++++ tools/ifconfig/af_inet6.c | 5 +++++ 5 files changed, 57 insertions(+), 6 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 3c42b99cf..6ef783e8f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -485,6 +485,10 @@ NETINET6_SRCS+= \ #ip6_ipsec.c #sctp6_usrreq.c #in6_rss.c +ifndef FF_KNI +FF_HOST_SRCS+= \ + ff_dpdk_kni.c +endif endif ifdef FF_IPFW diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 0bb7d0068..b90da90ab 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -67,7 +67,7 @@ #define KNI_MBUF_MAX 2048 #define KNI_QUEUE_SIZE 2048 -static int enable_kni; +int enable_kni; static int kni_accept; #endif @@ -848,6 +848,13 @@ protocol_filter(const void *data, uint16_t len) if(eth_frame_type == ETHER_TYPE_ARP) return FILTER_ARP; +#ifdef INET6 + if (eth_frame_type == ETHER_TYPE_IPv6) { + return ff_kni_proto_filter(data + ETHER_HDR_LEN, + len - ETHER_HDR_LEN, eth_frame_type); + } +#endif + #ifndef FF_KNI return FILTER_UNKNOWN; #else @@ -855,11 +862,7 @@ protocol_filter(const void *data, uint16_t len) return FILTER_UNKNOWN; } - if(eth_frame_type != ETHER_TYPE_IPv4 -#ifdef INET6 - && eth_frame_type != ETHER_TYPE_IPv6 -#endif - ) + if(eth_frame_type != ETHER_TYPE_IPv4) return FILTER_UNKNOWN; return ff_kni_proto_filter(data + ETHER_HDR_LEN, @@ -975,7 +978,11 @@ process_packets(uint16_t port_id, uint16_t queue_id, struct rte_mbuf **bufs, } enum FilterReturn filter = protocol_filter(data, len); +#ifdef INET6 + if (filter == FILTER_ARP || filter == FILTER_NDP) { +#else if (filter == FILTER_ARP) { +#endif struct rte_mempool *mbuf_pool; struct rte_mbuf *mbuf_clone; if (!pkts_from_ring) { diff --git a/lib/ff_dpdk_kni.c b/lib/ff_dpdk_kni.c index e024f9e9b..7f90f8971 100644 --- a/lib/ff_dpdk_kni.c +++ b/lib/ff_dpdk_kni.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -368,6 +369,21 @@ get_ipv6_hdr_len(uint8_t *proto, void *data, uint16_t len) return ext_hdr_len; } + +static enum FilterReturn +protocol_filter_icmp6(void *data, uint16_t len) +{ + if (len < sizeof(struct icmp6_hdr)) + return FILTER_UNKNOWN; + + const struct icmp6_hdr *hdr; + hdr = (const struct icmp6_hdr *)data; + + if (hdr->icmp6_type >= ND_ROUTER_SOLICIT && hdr->icmp6_type <= ND_REDIRECT) + return FILTER_NDP; + + return FILTER_UNKNOWN; +} #endif static enum FilterReturn @@ -409,14 +425,28 @@ protocol_filter_ip(const void *data, uint16_t len, uint16_t eth_frame_type) switch (proto) { case IPPROTO_TCP: +#ifdef FF_KNI + if (!enable_kni) + break; +#else + break; +#endif return protocol_filter_tcp(next, next_len); case IPPROTO_UDP: +#ifdef FF_KNI + if (!enable_kni) + break; +#else + break; +#endif return protocol_filter_udp(next, next_len); case IPPROTO_IPIP: return protocol_filter_ip(next, next_len, ETHER_TYPE_IPv4); #ifdef INET6 case IPPROTO_IPV6: return protocol_filter_ip(next, next_len, ETHER_TYPE_IPv6); + case IPPROTO_ICMPV6: + return protocol_filter_icmp6(next, next_len); #endif } diff --git a/lib/ff_dpdk_kni.h b/lib/ff_dpdk_kni.h index 197c9dae2..2ddf7a0de 100644 --- a/lib/ff_dpdk_kni.h +++ b/lib/ff_dpdk_kni.h @@ -31,10 +31,15 @@ #include #include +extern int enable_kni; + enum FilterReturn { FILTER_UNKNOWN = -1, FILTER_ARP = 1, FILTER_KNI = 2, +#ifdef INET6 + FILTER_NDP = 3, // Neighbor Solicitation/Advertisement, Router Solicitation/Advertisement/Redirect +#endif }; void ff_kni_init(uint16_t nb_ports, const char *tcp_ports, diff --git a/tools/ifconfig/af_inet6.c b/tools/ifconfig/af_inet6.c index 9dd3795c0..b18f3839d 100644 --- a/tools/ifconfig/af_inet6.c +++ b/tools/ifconfig/af_inet6.c @@ -104,7 +104,12 @@ setip6lifetime(const char *cmd, const char *val, int s, time_t newval; char *ep; +#ifndef FSTACK clock_gettime(CLOCK_MONOTONIC_FAST, &now); +#else + clock_gettime(CLOCK_MONOTONIC, &now); +#endif + newval = (time_t)strtoul(val, &ep, 0); if (val == ep) errx(1, "invalid %s", cmd);