-print_ipv6_key(struct ipv6_5tuple key)
-{
- printf( "IP dst = " IPv6_BYTES_FMT ", IP src = " IPv6_BYTES_FMT ", "
- "port dst = %d, port src = %d, proto = %d\n",
- IPv6_BYTES(key.ip_dst), IPv6_BYTES(key.ip_src),
- key.port_dst, key.port_src, key.proto);
-}
-
-static inline uint8_t
-get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid, lookup_struct_t * ipv4_l3fwd_lookup_struct)
-{
- struct ipv4_5tuple key;
- struct tcp_hdr *tcp;
- struct udp_hdr *udp;
- int ret = 0;
-
- key.ip_dst = rte_be_to_cpu_32(ipv4_hdr->dst_addr);
- key.ip_src = rte_be_to_cpu_32(ipv4_hdr->src_addr);
- key.proto = ipv4_hdr->next_proto_id;
-
- switch (ipv4_hdr->next_proto_id) {
- case IPPROTO_TCP:
- tcp = (struct tcp_hdr *)((unsigned char *) ipv4_hdr +
- sizeof(struct ipv4_hdr));
- key.port_dst = rte_be_to_cpu_16(tcp->dst_port);
- key.port_src = rte_be_to_cpu_16(tcp->src_port);
- break;
-
- case IPPROTO_UDP:
- udp = (struct udp_hdr *)((unsigned char *) ipv4_hdr +
- sizeof(struct ipv4_hdr));
- key.port_dst = rte_be_to_cpu_16(udp->dst_port);
- key.port_src = rte_be_to_cpu_16(udp->src_port);
- break;
-
- default:
- key.port_dst = 0;
- key.port_src = 0;
- break;
- }
-
- /* Find destination port */
- ret = rte_hash_lookup(ipv4_l3fwd_lookup_struct, (const void *)&key);
- return (uint8_t)((ret < 0)? portid : ipv4_l3fwd_out_if[ret]);
-}
-
-static inline uint8_t
-get_ipv6_dst_port(struct ipv6_hdr *ipv6_hdr, uint8_t portid, lookup_struct_t * ipv6_l3fwd_lookup_struct)
-{
- struct ipv6_5tuple key;
- struct tcp_hdr *tcp;
- struct udp_hdr *udp;
- int ret = 0;
-
- memcpy(key.ip_dst, ipv6_hdr->dst_addr, IPV6_ADDR_LEN);
- memcpy(key.ip_src, ipv6_hdr->src_addr, IPV6_ADDR_LEN);
-
- key.proto = ipv6_hdr->proto;
-
- switch (ipv6_hdr->proto) {
- case IPPROTO_TCP:
- tcp = (struct tcp_hdr *)((unsigned char *) ipv6_hdr +
- sizeof(struct ipv6_hdr));
- key.port_dst = rte_be_to_cpu_16(tcp->dst_port);
- key.port_src = rte_be_to_cpu_16(tcp->src_port);
- break;
-
- case IPPROTO_UDP:
- udp = (struct udp_hdr *)((unsigned char *) ipv6_hdr +
- sizeof(struct ipv6_hdr));
- key.port_dst = rte_be_to_cpu_16(udp->dst_port);
- key.port_src = rte_be_to_cpu_16(udp->src_port);
- break;
-
- default:
- key.port_dst = 0;
- key.port_src = 0;
- break;
- }
-
- /* Find destination port */
- ret = rte_hash_lookup(ipv6_l3fwd_lookup_struct, (const void *)&key);
- return (uint8_t)((ret < 0)? portid : ipv6_l3fwd_out_if[ret]);
-}
-#endif
-
-#if (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
-static inline uint8_t
-get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid, lookup_struct_t * ipv4_l3fwd_lookup_struct)
-{
- uint8_t next_hop;
-
- return (uint8_t) ((rte_lpm_lookup(ipv4_l3fwd_lookup_struct,
- rte_be_to_cpu_32(ipv4_hdr->dst_addr), &next_hop) == 0)?
- next_hop : portid);
-}
-#endif
-
-static inline void
-l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid, struct lcore_conf *qconf)
-{
- struct ether_hdr *eth_hdr;
- struct ipv4_hdr *ipv4_hdr;
- void *d_addr_bytes;
- uint8_t dst_port;
-
- eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
-
- if (m->ol_flags & PKT_RX_IPV4_HDR) {
- /* Handle IPv4 headers.*/
- ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, unsigned char *) +
- sizeof(struct ether_hdr));
-
-#ifdef DO_RFC_1812_CHECKS
- /* Check to make sure the packet is valid (RFC1812) */
- if (is_valid_ipv4_pkt(ipv4_hdr, m->pkt.pkt_len) < 0) {
- rte_pktmbuf_free(m);
- return;
- }
-#endif
-
- dst_port = get_ipv4_dst_port(ipv4_hdr, portid, qconf->ipv4_lookup_struct);
- if (dst_port >= MAX_PORTS || (enabled_port_mask & 1 << dst_port) == 0)
- dst_port = portid;
-
- /* 02:00:00:00:00:xx */
- d_addr_bytes = ð_hdr->d_addr.addr_bytes[0];
- *((uint64_t *)d_addr_bytes) = 0x000000000002 + ((uint64_t)dst_port << 40);
-
-#ifdef DO_RFC_1812_CHECKS
- /* Update time to live and header checksum */
- --(ipv4_hdr->time_to_live);
- ++(ipv4_hdr->hdr_checksum);
-#endif
-
- /* src addr */
- ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
-
- send_single_packet(m, dst_port);
- }
- else {
- /* Handle IPv6 headers.*/
-#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
- struct ipv6_hdr *ipv6_hdr;
-
- ipv6_hdr = (struct ipv6_hdr *)(rte_pktmbuf_mtod(m, unsigned char *) +
- sizeof(struct ether_hdr));
-
- dst_port = get_ipv6_dst_port(ipv6_hdr, portid, qconf->ipv6_lookup_struct);
-
- if (dst_port >= MAX_PORTS || (enabled_port_mask & 1 << dst_port) == 0)
- dst_port = portid;
-
- /* 02:00:00:00:00:xx */
- d_addr_bytes = ð_hdr->d_addr.addr_bytes[0];
- *((uint64_t *)d_addr_bytes) = 0x000000000002 + ((uint64_t)dst_port << 40);
-
- /* src addr */
- ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr);
-
- send_single_packet(m, dst_port);
-#else
- /* We don't currently handle IPv6 packets in LPM mode. */
- rte_pktmbuf_free(m);
-#endif
- }
-
-}
-
-/* main processing loop */
-static __attribute__((noreturn)) int
-main_loop(__attribute__((unused)) void *dummy)