Added support for VLAN in IPv6 28/70528/2
authorXavier Simonart <xavier.simonart@intel.com>
Sat, 11 Jul 2020 13:51:47 +0000 (15:51 +0200)
committerXavier Simonart <xavier.simonart@intel.com>
Mon, 21 Sep 2020 08:09:46 +0000 (10:09 +0200)
Change-Id: Ib1b3d54f9cb8e4284eee7ed0998e96370762a17e
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
VNFs/DPPD-PROX/handle_master.c
VNFs/DPPD-PROX/packet_utils.c
VNFs/DPPD-PROX/prox_ipv6.c
VNFs/DPPD-PROX/prox_ipv6.h
VNFs/DPPD-PROX/rx_pkt.c

index b0dbc9c..3be5581 100644 (file)
@@ -420,6 +420,7 @@ static inline void handle_unknown_ip6(struct task_base *tbase, struct rte_mbuf *
        struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *);
        uint8_t port = get_port(mbuf);
        struct ipv6_addr *ip_dst = ctrl_ring_get_ipv6_addr(mbuf);
+       uint16_t vlan = ctrl_ring_get_vlan(mbuf);
        int ret1, ret2, i;
 
        plogx_dbg("\tMaster trying to find MAC of external IP "IPv6_BYTES_FMT" for port %d\n", IPv6_BYTES(ip_dst->bytes), port);
@@ -479,32 +480,28 @@ static inline void handle_unknown_ip6(struct task_base *tbase, struct rte_mbuf *
 
        // As timers are not handled by master, we might send an NS request even if one was just sent
        // (and not yet answered) by another task
-       build_neighbour_sollicitation(mbuf, &task->internal_port_table[port].mac, ip_dst, ip_src);
+       build_neighbour_sollicitation(mbuf, &task->internal_port_table[port].mac, ip_dst, ip_src, vlan);
        tx_ring(tbase, ring, SEND_NDP_FROM_MASTER, mbuf);
 }
 
-static inline void handle_rs(struct task_base *tbase, struct rte_mbuf *mbuf)
+static inline void handle_rs(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ipv6_hdr *ipv6_hdr, uint16_t vlan)
 {
        struct task_master *task = (struct task_master *)tbase;
-       prox_rte_ether_hdr *hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(hdr + 1);
        int i, ret;
        uint8_t port = get_port(mbuf);
 
        if (task->internal_port_table[port].flags & IPV6_ROUTER) {
                plogx_dbg("\tMaster handling Router Solicitation from ip "IPv6_BYTES_FMT" on port %d\n", IPv6_BYTES(ipv6_hdr->src_addr), port);
                struct rte_ring *ring = task->internal_port_table[port].ring;
-               build_router_advertisement(mbuf, &prox_port_cfg[port].eth_addr, &task->internal_port_table[port].local_ipv6_addr, &task->internal_port_table[port].router_prefix);
+               build_router_advertisement(mbuf, &prox_port_cfg[port].eth_addr, &task->internal_port_table[port].local_ipv6_addr, &task->internal_port_table[port].router_prefix, vlan);
                tx_ring(tbase, ring, SEND_NDP_FROM_MASTER, mbuf);
                return;
        }
 }
 
-static inline void handle_ra(struct task_base *tbase, struct rte_mbuf *mbuf)
+static inline void handle_ra(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ipv6_hdr *ipv6_hdr, uint16_t vlan)
 {
        struct task_master *task = (struct task_master *)tbase;
-       prox_rte_ether_hdr *hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(hdr + 1);
        int i, ret, send = 0;
        uint8_t port = get_port(mbuf);
        struct rte_ring *ring = task->internal_port_table[port].ring;
@@ -559,11 +556,9 @@ static inline void handle_ra(struct task_base *tbase, struct rte_mbuf *mbuf)
                tx_drop(mbuf);
 }
 
-static inline void handle_ns(struct task_base *tbase, struct rte_mbuf *mbuf)
+static inline void handle_ns(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ipv6_hdr *ipv6_hdr, uint16_t vlan)
 {
        struct task_master *task = (struct task_master *)tbase;
-       prox_rte_ether_hdr *hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(hdr + 1);
        struct icmpv6_NS *neighbour_sollicitation = (struct icmpv6_NS *)(ipv6_hdr + 1);
        int i, ret;
        uint8_t port = get_port(mbuf);
@@ -606,7 +601,7 @@ static inline void handle_ns(struct task_base *tbase, struct rte_mbuf *mbuf)
                        plogx_dbg("\tMaster handling NS request for ip "IPv6_BYTES_FMT" on port %d which supports random ip\n", IPv6_BYTES(key.ip6.bytes), key.port);
                        struct rte_ring *ring = task->internal_port_table[port].ring;
                        create_mac_from_EUI(&key.ip6, &mac);
-                       build_neighbour_advertisement(tbase, mbuf, &mac, &task->internal_port_table[port].local_ipv6_addr, PROX_SOLLICITED);
+                       build_neighbour_advertisement(tbase, mbuf, &mac, &task->internal_port_table[port].local_ipv6_addr, PROX_SOLLICITED, vlan);
                        tx_ring(tbase, ring, SEND_NDP_FROM_MASTER, mbuf);
                        return;
                }
@@ -616,7 +611,7 @@ static inline void handle_ns(struct task_base *tbase, struct rte_mbuf *mbuf)
                        plogx_dbg("\tMaster handling NS request for ip "IPv6_BYTES_FMT" on port %d which supports random ip\n", IPv6_BYTES(key.ip6.bytes), key.port);
                        struct rte_ring *ring = task->internal_port_table[port].ring;
                        create_mac_from_EUI(&key.ip6, &mac);
-                       build_neighbour_advertisement(tbase, mbuf, &mac, &task->internal_port_table[port].global_ipv6_addr, PROX_SOLLICITED);
+                       build_neighbour_advertisement(tbase, mbuf, &mac, &task->internal_port_table[port].global_ipv6_addr, PROX_SOLLICITED, vlan);
                        tx_ring(tbase, ring, SEND_NDP_FROM_MASTER, mbuf);
                        return;
                }
@@ -629,16 +624,14 @@ static inline void handle_ns(struct task_base *tbase, struct rte_mbuf *mbuf)
                tx_drop(mbuf);
        } else {
                struct rte_ring *ring = task->internal_ip6_table[ret].ring;
-               build_neighbour_advertisement(tbase, mbuf, &task->internal_ip6_table[ret].mac, &key.ip6, PROX_SOLLICITED);
+               build_neighbour_advertisement(tbase, mbuf, &task->internal_ip6_table[ret].mac, &key.ip6, PROX_SOLLICITED, vlan);
                tx_ring(tbase, ring, SEND_NDP_FROM_MASTER, mbuf);
        }
 }
 
-static inline void handle_na(struct task_base *tbase, struct rte_mbuf *mbuf)
+static inline void handle_na(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ipv6_hdr *ipv6_hdr, uint16_t vlan)
 {
        struct task_master *task = (struct task_master *)tbase;
-       prox_rte_ether_hdr *hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(hdr + 1);
        struct icmpv6_NA *neighbour_advertisement = (struct icmpv6_NA *)(ipv6_hdr + 1);
        int i, ret;
        uint8_t port = get_port(mbuf);
@@ -716,7 +709,7 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf
        int command = get_command(mbuf);
        uint8_t port = get_port(mbuf);
        uint32_t ip;
-       uint16_t vlan, ether_type;
+       uint16_t vlan = 0, ether_type;
        uint8_t vdev_port = prox_port_cfg[port].dpdk_mapping;
        plogx_dbg("\tMaster received %s (%x) from mbuf %p\n", actions_string[command], command, mbuf);
        struct my_arp_t *arp;
@@ -828,10 +821,10 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf
                break;
        case NDP_PKT_FROM_NET_TO_MASTER:
                ether_hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
-               prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(ether_hdr + 1);
-               if (unlikely((ether_hdr->ether_type != ETYPE_IPv6) || (ipv6_hdr->proto != ICMPv6))) {
+               prox_rte_ipv6_hdr *ipv6_hdr = prox_get_ipv6_hdr(ether_hdr, rte_pktmbuf_pkt_len(mbuf), &vlan);
+               if (unlikely((!ipv6_hdr) || (ipv6_hdr->proto != ICMPv6))) {
                        // Should not happen
-                       if (ether_hdr->ether_type != ETYPE_IPv6)
+                       if (!ipv6_hdr)
                                plog_err("\tUnexpected message received: NDP_PKT_FROM_NET_TO_MASTER with ether_type %x\n", ether_hdr->ether_type);
                        else
                                plog_err("\tUnexpected message received: NDP_PKT_FROM_NET_TO_MASTER with ether_type %x and proto %x\n", ether_hdr->ether_type, ipv6_hdr->proto);
@@ -857,16 +850,16 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf
                        tx_drop(mbuf);
                        break;
                case ICMPv6_RS:
-                       handle_rs(tbase, mbuf);
+                       handle_rs(tbase, mbuf, ipv6_hdr, vlan);
                        break;
                case ICMPv6_RA:
-                       handle_ra(tbase, mbuf);
+                       handle_ra(tbase, mbuf, ipv6_hdr, vlan);
                        break;
                case ICMPv6_NS:
-                       handle_ns(tbase, mbuf);
+                       handle_ns(tbase, mbuf, ipv6_hdr, vlan);
                        break;
                case ICMPv6_NA:
-                       handle_na(tbase, mbuf);
+                       handle_na(tbase, mbuf, ipv6_hdr, vlan);
                        break;
                case ICMPv6_RE:
                        plog_err("IPV6 ICMPV6 Redirect not handled\n");
index a12281d..7be978d 100644 (file)
@@ -152,7 +152,7 @@ void send_unsollicited_neighbour_advertisement(struct task_base *tbase)
                ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&mbuf);
                if (likely(ret == 0)) {
                        mbuf->port = port_id;
-                       build_neighbour_advertisement(tbase->l3.tmaster, mbuf, &prox_port_cfg[port_id].eth_addr, &tbase->l3.local_ipv6, PROX_UNSOLLICITED);
+                       build_neighbour_advertisement(tbase->l3.tmaster, mbuf, &prox_port_cfg[port_id].eth_addr, &tbase->l3.local_ipv6, PROX_UNSOLLICITED, prox_port_cfg[port_id].vlan_tag);
                        tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out);
                        TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1);
                } else {
@@ -164,7 +164,7 @@ void send_unsollicited_neighbour_advertisement(struct task_base *tbase)
                ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&mbuf);
                if (likely(ret == 0)) {
                        mbuf->port = port_id;
-                       build_neighbour_advertisement(tbase->l3.tmaster, mbuf, &prox_port_cfg[port_id].eth_addr, &tbase->l3.global_ipv6, PROX_UNSOLLICITED);
+                       build_neighbour_advertisement(tbase->l3.tmaster, mbuf, &prox_port_cfg[port_id].eth_addr, &tbase->l3.global_ipv6, PROX_UNSOLLICITED, prox_port_cfg[port_id].vlan_tag);
                        tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out);
                        TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1);
                } else {
@@ -186,7 +186,7 @@ static void send_router_sollicitation(struct task_base *tbase, struct task_args
        ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&mbuf);
        if (likely(ret == 0)) {
                mbuf->port = port_id;
-               build_router_sollicitation(mbuf, &prox_port_cfg[port_id].eth_addr, &targ->local_ipv6);
+               build_router_sollicitation(mbuf, &prox_port_cfg[port_id].eth_addr, &targ->local_ipv6, prox_port_cfg[port_id].vlan_tag);
                tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out);
                TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1);
        } else {
index 9425f4a..9053823 100644 (file)
@@ -119,7 +119,25 @@ void create_mac_from_EUI(struct ipv6_addr *ipv6_addr, prox_rte_ether_addr *mac)
        mac->addr_bytes[0] = mac->addr_bytes[0] ^ 0x02;
        memcpy(&mac->addr_bytes[3], &ipv6_addr->bytes[13], 3);
 }
-void build_router_advertisement(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr, struct ipv6_addr *router_prefix)
+
+static inline prox_rte_ipv6_hdr *prox_set_vlan_ipv6(prox_rte_ether_hdr *peth, uint16_t vlan)
+{
+       prox_rte_ipv6_hdr *ipv6_hdr;
+
+       if (vlan) {
+               prox_rte_vlan_hdr *vlan_hdr = (prox_rte_vlan_hdr *)(peth + 1);
+               ipv6_hdr = (prox_rte_ipv6_hdr *)(vlan_hdr + 1);
+               peth->ether_type = ETYPE_VLAN;
+               vlan_hdr->eth_proto = ETYPE_IPv6;
+               vlan_hdr->vlan_tci = rte_cpu_to_be_16(vlan);
+       } else {
+               ipv6_hdr = (prox_rte_ipv6_hdr *)(peth + 1);
+               peth->ether_type = ETYPE_IPv6;
+       }
+       return ipv6_hdr;
+}
+
+void build_router_advertisement(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr, struct ipv6_addr *router_prefix, uint16_t vlan)
 {
        prox_rte_ether_hdr *peth = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
        init_mbuf_seg(mbuf);
@@ -127,9 +145,8 @@ void build_router_advertisement(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_ad
 
        memcpy(peth->d_addr.addr_bytes, &prox_cfg.all_nodes_mac_addr, sizeof(prox_rte_ether_addr));
        memcpy(peth->s_addr.addr_bytes, s_addr, sizeof(prox_rte_ether_addr));
-       peth->ether_type = ETYPE_IPv6;
 
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(peth + 1);
+       prox_rte_ipv6_hdr *ipv6_hdr = prox_set_vlan_ipv6(peth, vlan);
        ipv6_hdr->vtc_flow = 0x00000060;
        ipv6_hdr->payload_len = rte_cpu_to_be_16(sizeof(struct icmpv6_RA) + sizeof(struct icmpv6_prefix_option));
        ipv6_hdr->proto = ICMPv6;
@@ -165,11 +182,11 @@ void build_router_advertisement(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_ad
        router_advertisement->checksum = rte_ipv6_udptcp_cksum(ipv6_hdr, router_advertisement);
 
        uint16_t pktlen = rte_be_to_cpu_16(ipv6_hdr->payload_len) + sizeof(prox_rte_ipv6_hdr) + sizeof(prox_rte_ether_hdr);
-       rte_pktmbuf_pkt_len(mbuf) = pktlen;
-       rte_pktmbuf_data_len(mbuf) = pktlen;
+       rte_pktmbuf_pkt_len(mbuf) = pktlen + (vlan ? 4 : 0);
+       rte_pktmbuf_data_len(mbuf) = pktlen + (vlan ? 4 : 0);
 }
 
-void build_router_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr)
+void build_router_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr, uint16_t vlan)
 {
        prox_rte_ether_hdr *peth = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
 
@@ -178,9 +195,8 @@ void build_router_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_ad
 
        memcpy(peth->d_addr.addr_bytes, &prox_cfg.all_routers_mac_addr, sizeof(prox_rte_ether_addr));
        memcpy(peth->s_addr.addr_bytes, s_addr, sizeof(prox_rte_ether_addr));
-       peth->ether_type = ETYPE_IPv6;
 
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(peth + 1);
+       prox_rte_ipv6_hdr *ipv6_hdr = prox_set_vlan_ipv6(peth, vlan);
        ipv6_hdr->vtc_flow = 0x00000060;
        ipv6_hdr->payload_len = rte_cpu_to_be_16(sizeof(struct icmpv6_RS));
        ipv6_hdr->proto = ICMPv6;
@@ -198,11 +214,11 @@ void build_router_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_ad
        router_sollicitation->checksum = 0;
        router_sollicitation->checksum = rte_ipv6_udptcp_cksum(ipv6_hdr, router_sollicitation);
        uint16_t pktlen = rte_be_to_cpu_16(ipv6_hdr->payload_len) + sizeof(prox_rte_ipv6_hdr) + sizeof(prox_rte_ether_hdr);
-       rte_pktmbuf_pkt_len(mbuf) = pktlen;
-       rte_pktmbuf_data_len(mbuf) = pktlen;
+       rte_pktmbuf_pkt_len(mbuf) = pktlen + (vlan ? 4 : 0);
+       rte_pktmbuf_data_len(mbuf) = pktlen + (vlan ? 4 : 0);
 }
 
-void build_neighbour_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *dst, struct ipv6_addr *src)
+void build_neighbour_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *dst, struct ipv6_addr *src, uint16_t vlan)
 {
        prox_rte_ether_hdr *peth = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
        prox_rte_ether_addr mac_dst;
@@ -213,9 +229,9 @@ void build_neighbour_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s
 
        memcpy(peth->d_addr.addr_bytes, &mac_dst, sizeof(prox_rte_ether_addr));
        memcpy(peth->s_addr.addr_bytes, s_addr, sizeof(prox_rte_ether_addr));
-       peth->ether_type = ETYPE_IPv6;
 
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(peth + 1);
+       prox_rte_ipv6_hdr *ipv6_hdr = prox_set_vlan_ipv6(peth, vlan);
+
        ipv6_hdr->vtc_flow = 0x00000060;
        ipv6_hdr->payload_len = rte_cpu_to_be_16(sizeof(struct icmpv6_NS));
        ipv6_hdr->proto = ICMPv6;
@@ -235,21 +251,22 @@ void build_neighbour_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s
        neighbour_sollicitation->checksum = rte_ipv6_udptcp_cksum(ipv6_hdr, neighbour_sollicitation);
 
        uint16_t pktlen = rte_be_to_cpu_16(ipv6_hdr->payload_len) + sizeof(prox_rte_ipv6_hdr) + sizeof(prox_rte_ether_hdr);
-       rte_pktmbuf_pkt_len(mbuf) = pktlen;
-       rte_pktmbuf_data_len(mbuf) = pktlen;
+       rte_pktmbuf_pkt_len(mbuf) = pktlen + (vlan ? 4 : 0);
+       rte_pktmbuf_data_len(mbuf) = pktlen + (vlan ? 4 : 0);
 }
 
-void build_neighbour_advertisement(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ether_addr *target, struct ipv6_addr *src_ipv6_addr, int sollicited)
+void build_neighbour_advertisement(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ether_addr *target, struct ipv6_addr *src_ipv6_addr, int sollicited, uint16_t vlan)
 {
        struct task_master *task = (struct task_master *)tbase;
        prox_rte_ether_hdr *peth = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
-       prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(peth + 1);
 
        uint8_t port_id = get_port(mbuf);
 
        init_mbuf_seg(mbuf);
        mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM);  // Software calculates the checksum
 
+       prox_rte_ipv6_hdr *ipv6_hdr = prox_set_vlan_ipv6(peth, vlan);
+
        // If source mac is null, use all_nodes_mac_addr.
        if ((!sollicited) || (memcmp(peth->s_addr.addr_bytes, &null_addr, sizeof(struct ipv6_addr)) == 0)) {
                memcpy(peth->d_addr.addr_bytes, &prox_cfg.all_nodes_mac_addr, sizeof(prox_rte_ether_addr));
@@ -260,7 +277,6 @@ void build_neighbour_advertisement(struct task_base *tbase, struct rte_mbuf *mbu
        }
 
        memcpy(peth->s_addr.addr_bytes, &task->internal_port_table[port_id].mac, sizeof(prox_rte_ether_addr));
-       peth->ether_type = ETYPE_IPv6;
 
        ipv6_hdr->vtc_flow = 0x00000060;
        ipv6_hdr->payload_len = rte_cpu_to_be_16(sizeof(struct icmpv6_NA));
@@ -297,6 +313,27 @@ void build_neighbour_advertisement(struct task_base *tbase, struct rte_mbuf *mbu
        neighbour_advertisement->checksum = 0;
        neighbour_advertisement->checksum = rte_ipv6_udptcp_cksum(ipv6_hdr, neighbour_advertisement);
        uint16_t pktlen = rte_be_to_cpu_16(ipv6_hdr->payload_len) + sizeof(prox_rte_ipv6_hdr) + sizeof(prox_rte_ether_hdr);
-       rte_pktmbuf_pkt_len(mbuf) = pktlen;
-       rte_pktmbuf_data_len(mbuf) = pktlen;
+       rte_pktmbuf_pkt_len(mbuf) = pktlen + (vlan ? 4 : 0);
+       rte_pktmbuf_data_len(mbuf) = pktlen + (vlan ? 4 : 0);
+}
+
+prox_rte_ipv6_hdr *prox_get_ipv6_hdr(prox_rte_ether_hdr *hdr, uint16_t len, uint16_t *vlan)
+{
+       prox_rte_vlan_hdr *vlan_hdr;
+       prox_rte_ipv6_hdr *ipv6_hdr;
+       uint16_t ether_type = hdr->ether_type;
+       uint16_t l2_len = sizeof(prox_rte_ether_hdr);
+       ipv6_hdr = (prox_rte_ipv6_hdr *)(hdr + 1);
+
+       while (((ether_type == ETYPE_8021ad) || (ether_type == ETYPE_VLAN)) && (l2_len + sizeof(prox_rte_vlan_hdr) < len)) {
+               vlan_hdr = (prox_rte_vlan_hdr *)((uint8_t *)hdr + l2_len);
+               l2_len +=4;
+               ether_type = vlan_hdr->eth_proto;
+               *vlan = rte_be_to_cpu_16(vlan_hdr->vlan_tci & 0xFF0F);
+               ipv6_hdr = (prox_rte_ipv6_hdr *)(vlan_hdr + 1);
+       }
+       if (ether_type == ETYPE_IPv6)
+               return ipv6_hdr;
+       else
+               return NULL;
 }
index 4803005..e2ae7d6 100644 (file)
@@ -132,9 +132,10 @@ void set_EUI(struct ipv6_addr *ipv6_addr, prox_rte_ether_addr *mac);
 void create_mac_from_EUI(struct ipv6_addr *ipv6_addr, prox_rte_ether_addr *mac);
 
 struct task_base;
-void build_router_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr);
-void build_router_advertisement(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr, struct ipv6_addr *router_prefix);
-void build_neighbour_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *dst, struct ipv6_addr *src);
-void build_neighbour_advertisement(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ether_addr *target_mac, struct ipv6_addr *ipv6_addr, int sollicited);
+prox_rte_ipv6_hdr *prox_get_ipv6_hdr(prox_rte_ether_hdr *hdr, uint16_t len, uint16_t *vlan);
+void build_router_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr, uint16_t vlan);
+void build_router_advertisement(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *ipv6_s_addr, struct ipv6_addr *router_prefix, uint16_t vlan);
+void build_neighbour_sollicitation(struct rte_mbuf *mbuf, prox_rte_ether_addr *s_addr, struct ipv6_addr *dst, struct ipv6_addr *src, uint16_t vlan);
+void build_neighbour_advertisement(struct task_base *tbase, struct rte_mbuf *mbuf, prox_rte_ether_addr *target_mac, struct ipv6_addr *ipv6_addr, int sollicited, uint16_t vlan);
 
 #endif /* _PROX_IP_V6_H_ */
index 1fd5ca8..e1756cb 100644 (file)
@@ -180,9 +180,11 @@ static inline int handle_l3(struct task_base *tbase, uint16_t nb_rx, struct rte_
 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]);
@@ -192,8 +194,8 @@ static inline int handle_ndp(struct task_base *tbase, uint16_t nb_rx, struct rte
                PREFETCH0(hdr[i]);
        }
        for (i = 0; i < nb_rx; i++) {
-               prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(hdr[i] + 1);
-               if (unlikely((hdr[i]->ether_type == ETYPE_IPv6) && (ipv6_hdr->proto == ICMPv6))) {
+               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++;