diff options
author | Xavier Simonart <xavier.simonart@intel.com> | 2020-07-11 15:51:47 +0200 |
---|---|---|
committer | Xavier Simonart <xavier.simonart@intel.com> | 2020-09-21 10:09:46 +0200 |
commit | 91a44713bf414610246df57478b406a5561b725f (patch) | |
tree | 03d5cb273d1ffef3d0d6a84079af325e6f323160 | |
parent | 4ed5504a428fea4290cfe8594f5ff62edf50b878 (diff) |
Added support for VLAN in IPv6
Change-Id: Ib1b3d54f9cb8e4284eee7ed0998e96370762a17e
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
-rw-r--r-- | VNFs/DPPD-PROX/handle_master.c | 43 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/packet_utils.c | 6 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_ipv6.c | 77 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_ipv6.h | 9 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/rx_pkt.c | 6 |
5 files changed, 87 insertions, 54 deletions
diff --git a/VNFs/DPPD-PROX/handle_master.c b/VNFs/DPPD-PROX/handle_master.c index b0dbc9ce..3be55810 100644 --- a/VNFs/DPPD-PROX/handle_master.c +++ b/VNFs/DPPD-PROX/handle_master.c @@ -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"); diff --git a/VNFs/DPPD-PROX/packet_utils.c b/VNFs/DPPD-PROX/packet_utils.c index a12281d2..7be978db 100644 --- a/VNFs/DPPD-PROX/packet_utils.c +++ b/VNFs/DPPD-PROX/packet_utils.c @@ -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 { diff --git a/VNFs/DPPD-PROX/prox_ipv6.c b/VNFs/DPPD-PROX/prox_ipv6.c index 9425f4a0..90538230 100644 --- a/VNFs/DPPD-PROX/prox_ipv6.c +++ b/VNFs/DPPD-PROX/prox_ipv6.c @@ -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; } diff --git a/VNFs/DPPD-PROX/prox_ipv6.h b/VNFs/DPPD-PROX/prox_ipv6.h index 48030054..e2ae7d61 100644 --- a/VNFs/DPPD-PROX/prox_ipv6.h +++ b/VNFs/DPPD-PROX/prox_ipv6.h @@ -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_ */ diff --git a/VNFs/DPPD-PROX/rx_pkt.c b/VNFs/DPPD-PROX/rx_pkt.c index 1fd5ca85..e1756cb3 100644 --- a/VNFs/DPPD-PROX/rx_pkt.c +++ b/VNFs/DPPD-PROX/rx_pkt.c @@ -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++; |