diff options
Diffstat (limited to 'VNFs')
-rw-r--r-- | VNFs/DPPD-PROX/arp.h | 76 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/cfgfile.c | 5 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/handle_arp.c | 6 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/handle_master.c | 79 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/packet_utils.c | 33 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/packet_utils.h | 4 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/parse_utils.c | 12 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/parse_utils.h | 1 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_args.c | 12 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_port_cfg.c | 28 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_port_cfg.h | 2 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/tx_pkt.c | 20 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/tx_pkt.h | 19 |
13 files changed, 200 insertions, 97 deletions
diff --git a/VNFs/DPPD-PROX/arp.h b/VNFs/DPPD-PROX/arp.h index c0f74cbb..3e8e0d90 100644 --- a/VNFs/DPPD-PROX/arp.h +++ b/VNFs/DPPD-PROX/arp.h @@ -47,54 +47,72 @@ struct ether_hdr_arp { struct my_arp_t arp; }; -static int arp_is_gratuitous(struct ether_hdr_arp *hdr) +static int arp_is_gratuitous(struct my_arp_t *arp) { - return hdr->arp.data.spa == hdr->arp.data.tpa; + return arp->data.spa == arp->data.tpa; } -static inline void build_arp_reply(struct ether_hdr_arp *hdr_arp, prox_rte_ether_addr *s_addr) +// This build an arp reply based on a an request +static inline void build_arp_reply(prox_rte_ether_hdr *ether_hdr, prox_rte_ether_addr *s_addr, struct my_arp_t *arp) { - uint32_t ip_source = hdr_arp->arp.data.spa; + uint32_t ip_source = arp->data.spa; - memcpy(hdr_arp->ether_hdr.d_addr.addr_bytes, hdr_arp->ether_hdr.s_addr.addr_bytes, sizeof(prox_rte_ether_addr)); - memcpy(hdr_arp->ether_hdr.s_addr.addr_bytes, s_addr, sizeof(prox_rte_ether_addr)); + memcpy(ether_hdr->d_addr.addr_bytes, ether_hdr->s_addr.addr_bytes, sizeof(prox_rte_ether_addr)); + memcpy(ether_hdr->s_addr.addr_bytes, s_addr, sizeof(prox_rte_ether_addr)); - hdr_arp->arp.data.spa = hdr_arp->arp.data.tpa; - hdr_arp->arp.data.tpa = ip_source; - hdr_arp->arp.oper = 0x200; - memcpy(&hdr_arp->arp.data.tha, &hdr_arp->arp.data.sha, sizeof(prox_rte_ether_addr)); - memcpy(&hdr_arp->arp.data.sha, s_addr, sizeof(prox_rte_ether_addr)); + arp->data.spa = arp->data.tpa; + arp->data.tpa = ip_source; + arp->oper = 0x200; + memcpy(&arp->data.tha, &arp->data.sha, sizeof(prox_rte_ether_addr)); + memcpy(&arp->data.sha, s_addr, sizeof(prox_rte_ether_addr)); } -static inline void build_arp_request(struct rte_mbuf *mbuf, prox_rte_ether_addr *src_mac, uint32_t ip_dst, uint32_t ip_src) +static inline void build_arp_request(struct rte_mbuf *mbuf, prox_rte_ether_addr *src_mac, uint32_t ip_dst, uint32_t ip_src, uint16_t vlan) { - struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); + struct ether_hdr_arp *hdr_arp; + prox_rte_vlan_hdr *vlan_hdr; + prox_rte_ether_hdr *ether_hdr; + struct my_arp_t *arp; uint64_t mac_bcast = 0xFFFFFFFFFFFF; - rte_pktmbuf_pkt_len(mbuf) = 42; - rte_pktmbuf_data_len(mbuf) = 42; init_mbuf_seg(mbuf); - memcpy(&hdr_arp->ether_hdr.d_addr.addr_bytes, &mac_bcast, 6); - memcpy(&hdr_arp->ether_hdr.s_addr.addr_bytes, src_mac, 6); - hdr_arp->ether_hdr.ether_type = ETYPE_ARP; - hdr_arp->arp.htype = 0x100, - hdr_arp->arp.ptype = 0x0008; - hdr_arp->arp.hlen = 6; - hdr_arp->arp.plen = 4; - hdr_arp->arp.oper = 0x100; - hdr_arp->arp.data.spa = ip_src; - hdr_arp->arp.data.tpa = ip_dst; - memset(&hdr_arp->arp.data.tha, 0, sizeof(prox_rte_ether_addr)); - memcpy(&hdr_arp->arp.data.sha, src_mac, sizeof(prox_rte_ether_addr)); + if (vlan) { + ether_hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); + vlan_hdr = (prox_rte_vlan_hdr *)(ether_hdr + 1); + arp = (struct my_arp_t *)(vlan_hdr + 1); + ether_hdr->ether_type = ETYPE_VLAN; + vlan_hdr->eth_proto = ETYPE_ARP; + vlan_hdr->vlan_tci = rte_cpu_to_be_16(vlan); + rte_pktmbuf_pkt_len(mbuf) = 42 + sizeof(prox_rte_vlan_hdr); + rte_pktmbuf_data_len(mbuf) = 42 + sizeof(prox_rte_vlan_hdr); + } else { + ether_hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); + arp = (struct my_arp_t *)(ether_hdr + 1); + ether_hdr->ether_type = ETYPE_ARP; + rte_pktmbuf_pkt_len(mbuf) = 42; + rte_pktmbuf_data_len(mbuf) = 42; + } + + memcpy(ðer_hdr->d_addr.addr_bytes, &mac_bcast, 6); + memcpy(ðer_hdr->s_addr.addr_bytes, src_mac, 6); + arp->htype = 0x100, + arp->ptype = 0x0008; + arp->hlen = 6; + arp->plen = 4; + arp->oper = 0x100; + arp->data.spa = ip_src; + arp->data.tpa = ip_dst; + memset(&arp->data.tha, 0, sizeof(prox_rte_ether_addr)); + memcpy(&arp->data.sha, src_mac, sizeof(prox_rte_ether_addr)); } -static void create_mac(struct ether_hdr_arp *hdr, prox_rte_ether_addr *addr) +static void create_mac(struct my_arp_t *arp, prox_rte_ether_addr *addr) { addr->addr_bytes[0] = 0x2; addr->addr_bytes[1] = 0; // Instead of sending a completely random MAC address, create the following MAC: // 02:00:x1:x2:x3:x4 where x1:x2:x3:x4 is the IP address - memcpy(addr->addr_bytes + 2, (uint32_t *)&hdr->arp.data.tpa, 4); + memcpy(addr->addr_bytes + 2, (uint32_t *)&arp->data.tpa, 4); } #endif /* _ARP_H_ */ diff --git a/VNFs/DPPD-PROX/cfgfile.c b/VNFs/DPPD-PROX/cfgfile.c index dc225075..2bc9e5f1 100644 --- a/VNFs/DPPD-PROX/cfgfile.c +++ b/VNFs/DPPD-PROX/cfgfile.c @@ -274,6 +274,11 @@ int cfg_parse(struct cfg_file *pcfg, struct cfg_section *psec) do { ret = fgets(buffer, sizeof(buffer), pcfg->pfile); + /* remove comments */ + if (*ret == ';') { + *ret = '\0'; + } + if (ret && *ret != '[') { size_t l = strlen(buffer); prox_strncpy(lines, buffer, max_len); diff --git a/VNFs/DPPD-PROX/handle_arp.c b/VNFs/DPPD-PROX/handle_arp.c index 2da98ef2..c0286d42 100644 --- a/VNFs/DPPD-PROX/handle_arp.c +++ b/VNFs/DPPD-PROX/handle_arp.c @@ -46,7 +46,7 @@ static void task_update_config(struct task_arp *task) static void handle_arp(struct task_arp *task, struct ether_hdr_arp *hdr, prox_rte_ether_addr *s_addr) { - build_arp_reply(hdr, s_addr); + build_arp_reply((prox_rte_ether_hdr *)hdr, s_addr, &hdr->arp); } static int handle_arp_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts) @@ -61,7 +61,7 @@ static int handle_arp_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin for (uint16_t j = 0; j < n_pkts; ++j) { hdr = rte_pktmbuf_mtod(mbufs[j], struct ether_hdr_arp *); if (hdr->ether_hdr.ether_type == ETYPE_ARP) { - if (arp_is_gratuitous(hdr)) { + if (arp_is_gratuitous(&hdr->arp)) { out[n_other_pkts] = OUT_DISCARD; n_other_pkts++; plog_info("Received gratuitous packet \n"); @@ -71,7 +71,7 @@ static int handle_arp_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin out[n_arp_pkts] = task->arp_replies_ring; n_arp_pkts++; } else if (task->ip == 0) { - create_mac(hdr, &s_addr); + create_mac(&hdr->arp, &s_addr); handle_arp(task, hdr, &s_addr); replies_mbufs[n_arp_reply_pkts] = mbufs[j]; out[n_arp_reply_pkts] = 0; diff --git a/VNFs/DPPD-PROX/handle_master.c b/VNFs/DPPD-PROX/handle_master.c index a528a681..8e03526f 100644 --- a/VNFs/DPPD-PROX/handle_master.c +++ b/VNFs/DPPD-PROX/handle_master.c @@ -173,7 +173,7 @@ void master_init_vdev(struct task_base *tbase, uint8_t port_id, uint8_t core_id, PROX_PANIC(fd < 0, "Failed to open socket(AF_INET, SOCK_DGRAM, 0)\n"); prox_port_cfg[vdev_port].fd = fd; rc = bind(fd,(struct sockaddr *)&src, sizeof(struct sockaddr_in)); - PROX_PANIC(rc, "Failed to bind("IPv4_BYTES_FMT":%d): errno = %d\n", IPv4_BYTES(((uint8_t*)&src.sin_addr.s_addr)), src.sin_port, errno); + PROX_PANIC(rc, "Failed to bind("IPv4_BYTES_FMT":%d): errno = %d (%s)\n", IPv4_BYTES(((uint8_t*)&src.sin_addr.s_addr)), src.sin_port, errno, strerror(errno)); plog_info("DPDK port %d bound("IPv4_BYTES_FMT":%d) to fd %d\n", port_id, IPv4_BYTES(((uint8_t*)&src.sin_addr.s_addr)), src.sin_port, fd); fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); task->max_vdev_id++; @@ -214,12 +214,11 @@ void register_ip_to_ctrl_plane(struct task_base *tbase, uint32_t ip, uint8_t por task->internal_ip_table[ret].ring = task->ctrl_tx_rings[core_id * MAX_TASKS_PER_CORE + task_id]; } -static inline void handle_arp_reply(struct task_base *tbase, struct rte_mbuf *mbuf) +static inline void handle_arp_reply(struct task_base *tbase, struct rte_mbuf *mbuf, struct my_arp_t *arp) { struct task_master *task = (struct task_master *)tbase; - struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); int i, ret; - uint32_t key = hdr_arp->arp.data.spa; + uint32_t key = arp->data.spa; plogx_dbg("\tMaster handling ARP reply for ip "IPv4_BYTES_FMT"\n", IP4(key)); ret = rte_hash_lookup(task->external_ip_hash, (const void *)&key); @@ -243,23 +242,23 @@ static inline void handle_arp_reply(struct task_base *tbase, struct rte_mbuf *mb } } -static inline void handle_arp_request(struct task_base *tbase, struct rte_mbuf *mbuf) +static inline void handle_arp_request(struct task_base *tbase, struct rte_mbuf *mbuf, struct my_arp_t *arp) { struct task_master *task = (struct task_master *)tbase; - struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); + prox_rte_ether_hdr *ether_hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); int i, ret; uint8_t port = get_port(mbuf); struct ip_port key; - key.ip = hdr_arp->arp.data.tpa; + key.ip = arp->data.tpa; key.port = port; if (task->internal_port_table[port].flags & HANDLE_RANDOM_IP_FLAG) { prox_rte_ether_addr mac; plogx_dbg("\tMaster handling ARP request for ip "IPv4_BYTES_FMT" on port %d which supports random ip\n", IP4(key.ip), key.port); struct rte_ring *ring = task->internal_port_table[port].ring; - create_mac(hdr_arp, &mac); + create_mac(arp, &mac); mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM); - build_arp_reply(hdr_arp, &mac); + build_arp_reply(ether_hdr, &mac, arp); tx_ring(tbase, ring, SEND_ARP_REPLY_FROM_MASTER, mbuf); return; } @@ -269,12 +268,12 @@ static inline void handle_arp_request(struct task_base *tbase, struct rte_mbuf * ret = rte_hash_lookup(task->internal_ip_hash, (const void *)&key); if (unlikely(ret < 0)) { // entry not found for this IP. - plogx_dbg("Master ignoring ARP REQUEST received on un-registered IP "IPv4_BYTES_FMT" on port %d\n", IP4(hdr_arp->arp.data.tpa), port); + plogx_dbg("Master ignoring ARP REQUEST received on un-registered IP "IPv4_BYTES_FMT" on port %d\n", IP4(arp->data.tpa), port); tx_drop(mbuf); } else { struct rte_ring *ring = task->internal_ip_table[ret].ring; mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM); - build_arp_reply(hdr_arp, &task->internal_ip_table[ret].mac); + build_arp_reply(ether_hdr, &task->internal_ip_table[ret].mac, arp); tx_ring(tbase, ring, SEND_ARP_REPLY_FROM_MASTER, mbuf); } } @@ -316,6 +315,7 @@ static inline void handle_unknown_ip(struct task_base *tbase, struct rte_mbuf *m struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); uint8_t port = get_port(mbuf); uint32_t ip_dst = get_ip(mbuf); + uint16_t vlan = ctrl_ring_get_vlan(mbuf); plogx_dbg("\tMaster handling unknown ip "IPv4_BYTES_FMT" for port %d\n", IP4(ip_dst), port); if (unlikely(port >= PROX_MAX_PORTS)) { @@ -338,7 +338,7 @@ static inline void handle_unknown_ip(struct task_base *tbase, struct rte_mbuf *m } // We send an ARP request even if one was just sent (and not yet answered) by another task mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM); - build_arp_request(mbuf, &task->internal_port_table[port].mac, ip_dst, ip_src); + build_arp_request(mbuf, &task->internal_port_table[port].mac, ip_dst, ip_src, vlan); tx_ring(tbase, ring, SEND_ARP_REQUEST_FROM_MASTER, mbuf); } @@ -710,14 +710,15 @@ static inline void handle_na(struct task_base *tbase, struct rte_mbuf *mbuf) static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf, int ring_id) { struct task_master *task = (struct task_master *)tbase; - struct ether_hdr_arp *hdr_arp; - prox_rte_ether_hdr *hdr; + prox_rte_ether_hdr *ether_hdr; struct icmpv6 *icmpv6; int command = get_command(mbuf); uint8_t port = get_port(mbuf); uint32_t ip; + uint16_t vlan, 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; switch(command) { case BGP_TO_MASTER: @@ -748,22 +749,32 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf int n = rte_eth_tx_burst(prox_port_cfg[port].dpdk_mapping, 0, &mbuf, 1); return; } - hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); - if (hdr_arp->ether_hdr.ether_type != ETYPE_ARP) { - plog_err("\tUnexpected message received: ARP_PKT_FROM_NET_TO_MASTER with ether_type %x\n", hdr_arp->ether_hdr.ether_type); + ether_hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); + ether_type = ether_hdr->ether_type; + if (ether_type == ETYPE_VLAN) { + prox_rte_vlan_hdr *vlan_hdr = (prox_rte_vlan_hdr *)(ether_hdr + 1); + arp = (struct my_arp_t *)(vlan_hdr + 1); + ether_type = vlan_hdr->eth_proto; + } else { + arp = (struct my_arp_t *)(ether_hdr + 1); + } + + if (ether_type != ETYPE_ARP) { + plog_err("\tUnexpected message received: ARP_PKT_FROM_NET_TO_MASTER with ether_type %x\n", ether_type); tx_drop(mbuf); return; - } else if (arp_is_gratuitous(hdr_arp)) { + } + if (arp_is_gratuitous(arp)) { plog_info("\tReceived gratuitous packet \n"); tx_drop(mbuf); return; - } else if (memcmp(&hdr_arp->arp, &arp_reply, 8) == 0) { - uint32_t ip = hdr_arp->arp.data.spa; - handle_arp_reply(tbase, mbuf); - } else if (memcmp(&hdr_arp->arp, &arp_request, 8) == 0) { - handle_arp_request(tbase, mbuf); + } else if (memcmp(arp, &arp_reply, 8) == 0) { + // uint32_t ip = arp->data.spa; + handle_arp_reply(tbase, mbuf, arp); + } else if (memcmp(arp, &arp_request, 8) == 0) { + handle_arp_request(tbase, mbuf, arp); } else { - plog_info("\tReceived unexpected ARP operation %d\n", hdr_arp->arp.oper); + plog_info("\tReceived unexpected ARP operation %d\n", arp->oper); tx_drop(mbuf); return; } @@ -798,8 +809,12 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf dst.sin_family = AF_INET; dst.sin_addr.s_addr = ip; dst.sin_port = rte_cpu_to_be_16(PROX_PSEUDO_PKT_PORT); - int n = sendto(prox_port_cfg[vdev_port].fd, (char*)(&ip), 0, 0, (struct sockaddr *)&dst, sizeof(struct sockaddr_in)); - plogx_dbg("\tSent %d bytes to TAP IP "IPv4_BYTES_FMT" using fd %d\n", n, IPv4_BYTES(((uint8_t*)&ip)), prox_port_cfg[vdev_port].fd); + // TODO VLAN: find the right fd based on the VLAN + int n = sendto(prox_port_cfg[vdev_port].fd, (char*)(&ip), 0, MSG_DONTROUTE, (struct sockaddr *)&dst, sizeof(struct sockaddr_in)); + if (n < 0) { + plogx_info("\tFailed to send to TAP IP "IPv4_BYTES_FMT" using fd %d, error = %d (%s)\n", IPv4_BYTES(((uint8_t*)&ip)), prox_port_cfg[vdev_port].fd, errno, strerror(errno)); + } else + plogx_dbg("\tSent %d bytes to TAP IP "IPv4_BYTES_FMT" using fd %d\n", n, IPv4_BYTES(((uint8_t*)&ip)), prox_port_cfg[vdev_port].fd); record_request(tbase, ip, port, ring); tx_drop(mbuf); @@ -811,14 +826,14 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf handle_unknown_ip6(tbase, mbuf); break; case NDP_PKT_FROM_NET_TO_MASTER: - hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); - prox_rte_ipv6_hdr *ipv6_hdr = (prox_rte_ipv6_hdr *)(hdr + 1); - if (unlikely((hdr->ether_type != ETYPE_IPv6) || (ipv6_hdr->proto != ICMPv6))) { + 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))) { // Should not happen - if (hdr->ether_type != ETYPE_IPv6) - plog_err("\tUnexpected message received: NDP_PKT_FROM_NET_TO_MASTER with ether_type %x\n", hdr->ether_type); + if (ether_hdr->ether_type != ETYPE_IPv6) + 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", hdr->ether_type, ipv6_hdr->proto); + 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); tx_drop(mbuf); return; } diff --git a/VNFs/DPPD-PROX/packet_utils.c b/VNFs/DPPD-PROX/packet_utils.c index 466dd481..9832a039 100644 --- a/VNFs/DPPD-PROX/packet_utils.c +++ b/VNFs/DPPD-PROX/packet_utils.c @@ -36,7 +36,7 @@ #include "prox_ipv6.h" #include "tx_pkt.h" -static inline int find_ip(struct ether_hdr_arp *pkt, uint16_t len, uint32_t *ip_dst) +static inline int find_ip(struct ether_hdr_arp *pkt, uint16_t len, uint32_t *ip_dst, uint16_t *vlan) { prox_rte_vlan_hdr *vlan_hdr; prox_rte_ether_hdr *eth_hdr = (prox_rte_ether_hdr*)pkt; @@ -44,11 +44,13 @@ static inline int find_ip(struct ether_hdr_arp *pkt, uint16_t len, uint32_t *ip_ uint16_t ether_type = eth_hdr->ether_type; uint16_t l2_len = sizeof(prox_rte_ether_hdr); + *vlan = 0; // Unstack VLAN tags 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 *)pkt + l2_len); l2_len +=4; ether_type = vlan_hdr->eth_proto; + *vlan = rte_be_to_cpu_16(vlan_hdr->vlan_tci & 0xFF0F); // Store VLAN, or CVLAN if QinQ } switch (ether_type) { @@ -79,18 +81,20 @@ static inline int find_ip(struct ether_hdr_arp *pkt, uint16_t len, uint32_t *ip_ return -1; } -static inline struct ipv6_addr *find_ip6(prox_rte_ether_hdr *pkt, uint16_t len, struct ipv6_addr *ip_dst) +static inline struct ipv6_addr *find_ip6(prox_rte_ether_hdr *pkt, uint16_t len, struct ipv6_addr *ip_dst, uint16_t *vlan) { prox_rte_vlan_hdr *vlan_hdr; prox_rte_ipv6_hdr *ip; uint16_t ether_type = pkt->ether_type; uint16_t l2_len = sizeof(prox_rte_ether_hdr); + *vlan = 0; // Unstack VLAN tags 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 *)pkt + l2_len); l2_len +=4; ether_type = vlan_hdr->eth_proto; + *vlan = rte_be_to_cpu_16(vlan_hdr->vlan_tci & 0xFF0F); // Store VLAN, or CVLAN if QinQ } switch (ether_type) { @@ -199,7 +203,7 @@ static inline int update_mac_and_send_mbuf(struct arp_table *entry, prox_rte_eth return DROP_MBUF; } -int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_dst, uint64_t **time, uint64_t tsc) +int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_dst, uint16_t *vlan, uint64_t **time, uint64_t tsc) { const uint64_t hz = rte_get_tsc_hz(); struct ether_hdr_arp *packet = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); @@ -215,7 +219,7 @@ int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_d // If a gw (gateway_ipv4) is also specified, it is used as default gw only i.e. lowest priority (shortest prefix) // This is implemented automatically through lpm uint16_t len = rte_pktmbuf_pkt_len(mbuf); - if (find_ip(packet, len, ip_dst) != 0) { + if (find_ip(packet, len, ip_dst, vlan) != 0) { // Unable to find IP address => non IP packet => send it as it return SEND_MBUF; } @@ -223,7 +227,7 @@ int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_d // Prevent printing too many messages n_no_route++; if (tsc > last_tsc + rte_get_tsc_hz()) { - plog_err("No route to IP "IPv4_BYTES_FMT" (%ld times)\n", IP4(*ip_dst), n_no_route); + plogx_err("No route to IP "IPv4_BYTES_FMT" (%ld times)\n", IP4(*ip_dst), n_no_route); last_tsc = tsc; n_no_route = 0; } @@ -275,7 +279,7 @@ int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_d } uint16_t len = rte_pktmbuf_pkt_len(mbuf); - if (find_ip(packet, len, ip_dst) != 0) { + if (find_ip(packet, len, ip_dst, vlan) != 0) { // Unable to find IP address => non IP packet => send it as it return SEND_MBUF; } @@ -324,7 +328,7 @@ int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_d return DROP_MBUF; } -int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst) +int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst, uint16_t *vlan) { const uint64_t hz = rte_get_tsc_hz(); prox_rte_ether_hdr *packet = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); @@ -335,7 +339,7 @@ int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv uint16_t len = rte_pktmbuf_pkt_len(mbuf); struct ipv6_addr *pkt_src_ip6; - if ((pkt_src_ip6 = find_ip6(packet, len, ip_dst)) == NULL) { + if ((pkt_src_ip6 = find_ip6(packet, len, ip_dst, vlan)) == NULL) { // Unable to find IP address => non IP packet => send it as it return SEND_MBUF; } @@ -507,6 +511,17 @@ void task_start_l3(struct task_base *tbase, struct task_args *targ) if (port && (tbase->l3.arp_nd_pool == NULL)) { static char name[] = "arp0_pool"; tbase->l3.reachable_port_id = port - prox_port_cfg; + if ((targ->local_ipv4 && port->ip) && (targ->local_ipv4 != port->ip)) { + PROX_PANIC(1, "local_ipv4 in core section ("IPv4_BYTES_FMT") differs from port section ("IPv4_BYTES_FMT")\n", IP4(rte_be_to_cpu_32(targ->local_ipv4)), IP4(rte_be_to_cpu_32(port->ip))); + } + if ((targ->local_ipv4 && port->ip) && (targ->local_prefix != port->prefix)) { + PROX_PANIC(1, "local_ipv4 prefix in core section (%d) differs from port section (%d)\n", targ->local_prefix, port->prefix); + } + if (!targ->local_ipv4) { + targ->local_ipv4 = port->ip; + targ->local_prefix = port->prefix; + plog_info("Setting core local_ipv4 from port %d local_ipv4 to "IPv4_BYTES_FMT"\n", tbase->l3.reachable_port_id, IP4(rte_be_to_cpu_32(port->ip))); + } if (targ->local_ipv4) { tbase->l3.local_ipv4 = rte_be_to_cpu_32(targ->local_ipv4); register_ip_to_ctrl_plane(tbase->l3.tmaster, tbase->l3.local_ipv4, tbase->l3.reachable_port_id, targ->lconf->id, targ->id); @@ -515,7 +530,7 @@ void task_start_l3(struct task_base *tbase, struct task_args *targ) struct lpm4 *lpm; int ret; - PROX_PANIC(tbase->l3.local_ipv4 == 0, "missing local_ipv4 will route table is specified in L3 mode\n"); + PROX_PANIC(tbase->l3.local_ipv4 == 0, "missing local_ipv4 while route table is specified in L3 mode\n"); // LPM might be modified runtime => do not share with other cores ret = lua_to_lpm4(prox_lua(), GLOBAL, targ->route_table, socket_id, &lpm); diff --git a/VNFs/DPPD-PROX/packet_utils.h b/VNFs/DPPD-PROX/packet_utils.h index ca4d449c..381a7687 100644 --- a/VNFs/DPPD-PROX/packet_utils.h +++ b/VNFs/DPPD-PROX/packet_utils.h @@ -76,8 +76,8 @@ struct l3_base { void task_init_l3(struct task_base *tbase, struct task_args *targ); void task_start_l3(struct task_base *tbase, struct task_args *targ); -int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_dst, uint64_t **time, uint64_t tsc); -int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst); +int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_dst, uint16_t *vlan, uint64_t **time, uint64_t tsc); +int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst, uint16_t *vlan); void task_set_gateway_ip(struct task_base *tbase, uint32_t ip); void task_set_local_ip(struct task_base *tbase, uint32_t ip); void handle_ctrl_plane_pkts(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts); diff --git a/VNFs/DPPD-PROX/parse_utils.c b/VNFs/DPPD-PROX/parse_utils.c index ab0e03b7..9ceb1c59 100644 --- a/VNFs/DPPD-PROX/parse_utils.c +++ b/VNFs/DPPD-PROX/parse_utils.c @@ -311,7 +311,7 @@ int parse_ip(uint32_t *addr, const char *str2) return 0; } -int parse_ip4_cidr(struct ip4_subnet *val, const char *str2) +int parse_ip4_and_prefix(struct ip4_subnet *val, const char *str2) { char str[MAX_STR_LEN_PROC]; char *slash; @@ -341,10 +341,16 @@ int parse_ip4_cidr(struct ip4_subnet *val, const char *str2) if (parse_ip(&val->ip, str)) return -2; + return 0; +} + +int parse_ip4_cidr(struct ip4_subnet *val, const char *str2) +{ + int rc = parse_ip4_and_prefix(val, str2); /* Apply mask making all bits outside the prefix zero */ - val->ip &= ((int)(1 << 31)) >> (prefix - 1); + val->ip &= ((int)(1 << 31)) >> (val->prefix - 1); - return 0; + return rc; } int parse_ip6_cidr(struct ip6_subnet *val, const char *str2) diff --git a/VNFs/DPPD-PROX/parse_utils.h b/VNFs/DPPD-PROX/parse_utils.h index 32c95f4e..5671e377 100644 --- a/VNFs/DPPD-PROX/parse_utils.h +++ b/VNFs/DPPD-PROX/parse_utils.h @@ -46,6 +46,7 @@ int parse_range(uint32_t* lo, uint32_t* hi, const char *saddr); /* parses CIDR notation. Note that bits within the address that are outside the subnet (as specified by the prefix) are set to 0. */ +int parse_ip4_and_prefix(struct ip4_subnet *val, const char *saddr); int parse_ip4_cidr(struct ip4_subnet *val, const char *saddr); int parse_ip6_cidr(struct ip6_subnet *val, const char *saddr); diff --git a/VNFs/DPPD-PROX/prox_args.c b/VNFs/DPPD-PROX/prox_args.c index 25599cb7..43f9d5fb 100644 --- a/VNFs/DPPD-PROX/prox_args.c +++ b/VNFs/DPPD-PROX/prox_args.c @@ -568,7 +568,15 @@ static int get_port_cfg(unsigned sindex, char *str, void *data) cfg->lsc_val = val; } else if (STR_EQ(str, "local ipv4")) { - return parse_ip(&cfg->ip, pkey); + struct ip4_subnet cidr; + if (parse_ip4_and_prefix(&cidr, pkey) != 0) { + cfg->prefix = 24; + return parse_ip(&cfg->ip, pkey); + } else { + cfg->ip = cidr.ip; + cfg->prefix = cidr.prefix; + return 0; + } } else if (STR_EQ(str, "vdev")) { prox_strncpy(cfg->vdev, pkey, MAX_NAME_SIZE); @@ -1474,7 +1482,7 @@ static int get_core_cfg(unsigned sindex, char *str, void *data) } if (STR_EQ(str, "local ipv4")) { /* source IP address to be used for packets */ struct ip4_subnet cidr; - if (parse_ip4_cidr(&cidr, pkey) != 0) { + if (parse_ip4_and_prefix(&cidr, pkey) != 0) { if (targ->gateway_ipv4) targ->local_prefix = 32; else diff --git a/VNFs/DPPD-PROX/prox_port_cfg.c b/VNFs/DPPD-PROX/prox_port_cfg.c index 2e19d25d..89824d69 100644 --- a/VNFs/DPPD-PROX/prox_port_cfg.c +++ b/VNFs/DPPD-PROX/prox_port_cfg.c @@ -165,24 +165,39 @@ void prox_pktmbuf_reinit(void *arg, void *start, __attribute__((unused)) void *e plog_info("\t\t%s disabled\n", #flag);\ }\ +static inline uint32_t get_netmask(uint8_t prefix) +{ + if (prefix == 0) + return(~((uint32_t) -1)); + else + return rte_cpu_to_be_32(~((1 << (32 - prefix)) - 1)); +} -static void set_ip_address (char *devname, uint32_t *ip) +static void set_ip_address(char *devname, uint32_t *ip, uint8_t prefix) { struct ifreq ifreq; struct sockaddr_in in_addr; int fd, rc; + uint32_t netmask = get_netmask(prefix); + plog_info("Setting netmask to %x\n", netmask); + + fd = socket(AF_INET, SOCK_DGRAM, 0); memset(&ifreq, 0, sizeof(struct ifreq)); memset(&in_addr, 0, sizeof(struct sockaddr_in)); in_addr.sin_family = AF_INET; in_addr.sin_addr = *(struct in_addr *)ip; - fd = socket(in_addr.sin_family, SOCK_DGRAM, 0); strncpy(ifreq.ifr_name, devname, IFNAMSIZ); ifreq.ifr_addr = *(struct sockaddr *)&in_addr; rc = ioctl(fd, SIOCSIFADDR, &ifreq); - PROX_PANIC(rc < 0, "Failed to set IP address %d on device %s: error = %d\n", *ip, devname, errno); + PROX_PANIC(rc < 0, "Failed to set IP address %x on device %s: error = %d (%s)\n", *ip, devname, errno, strerror(errno)); + + in_addr.sin_addr = *(struct in_addr *)&netmask; + ifreq.ifr_netmask = *(struct sockaddr *)&in_addr; + rc = ioctl(fd, SIOCSIFNETMASK, &ifreq); + PROX_PANIC(rc < 0, "Failed to set netmask %x (prefix %d) on device %s: error = %d (%s)\n", netmask, prefix, devname, errno, strerror(errno)); close(fd); } @@ -212,6 +227,7 @@ void init_rte_dev(int use_dummy_devices) int vdev_port_id = prox_rte_eth_dev_count_avail() - 1; PROX_PANIC(vdev_port_id >= PROX_MAX_PORTS, "Too many port defined %d >= %d\n", vdev_port_id, PROX_MAX_PORTS); plog_info("\tCreating device %s, port %d\n", port_cfg->vdev, vdev_port_id); + prox_port_cfg[vdev_port_id].is_vdev = 1; prox_port_cfg[vdev_port_id].active = 1; prox_port_cfg[vdev_port_id].dpdk_mapping = port_id; prox_port_cfg[vdev_port_id].n_txq = 1; @@ -228,7 +244,7 @@ void init_rte_dev(int use_dummy_devices) prox_port_cfg[port_id].dpdk_mapping = vdev_port_id; prox_port_cfg[vdev_port_id].ip = rte_be_to_cpu_32(prox_port_cfg[port_id].ip); - prox_port_cfg[port_id].ip = 0; // So only vdev has an IP associated + prox_port_cfg[vdev_port_id].prefix = prox_port_cfg[port_id].prefix; prox_port_cfg[vdev_port_id].type = prox_port_cfg[port_id].type; if (prox_port_cfg[vdev_port_id].type == PROX_PORT_MAC_HW) { // If DPDK port MAC set to HW, then make sure the vdev has the same MAC as DPDK port @@ -768,8 +784,8 @@ static void init_port(struct prox_port_cfg *port_cfg) PROX_PANIC(ret < 0, "\n\t\t\trte_eth_dev_start() failed on port %u: error %d\n", port_id, ret); plog_info(" done: "); - if (prox_port_cfg[port_id].ip) { - set_ip_address(prox_port_cfg[port_id].name, &prox_port_cfg[port_id].ip); + if ((prox_port_cfg[port_id].ip) && (prox_port_cfg[port_id].is_vdev)) { + set_ip_address(prox_port_cfg[port_id].name, &prox_port_cfg[port_id].ip, prox_port_cfg[port_id].prefix); } /* Getting link status can be done without waiting if Link State Interrupt is enabled since in that case, if the link diff --git a/VNFs/DPPD-PROX/prox_port_cfg.h b/VNFs/DPPD-PROX/prox_port_cfg.h index 94f2c41a..9d025999 100644 --- a/VNFs/DPPD-PROX/prox_port_cfg.h +++ b/VNFs/DPPD-PROX/prox_port_cfg.h @@ -85,6 +85,8 @@ struct prox_port_cfg { uint32_t ip; int fd; uint32_t vlan_tag; + uint8_t prefix; + uint8_t is_vdev; }; extern rte_atomic32_t lsc; diff --git a/VNFs/DPPD-PROX/tx_pkt.c b/VNFs/DPPD-PROX/tx_pkt.c index 60d6b514..f45516ec 100644 --- a/VNFs/DPPD-PROX/tx_pkt.c +++ b/VNFs/DPPD-PROX/tx_pkt.c @@ -66,11 +66,12 @@ int tx_pkt_ndp(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts int first = 0, ret, ok = 0, rc; const struct port_queue *port_queue = &tbase->tx_params_hw.tx_port_queue[0]; struct rte_mbuf *mbuf = NULL; // used when one need to send both an ARP and a mbuf + uint16_t vlan; for (int j = 0; j < n_pkts; j++) { if ((out) && (out[j] >= OUT_HANDLED)) continue; - if (unlikely((rc = write_ip6_dst_mac(tbase, mbufs[j], &ip_dst)) != SEND_MBUF)) { + if (unlikely((rc = write_ip6_dst_mac(tbase, mbufs[j], &ip_dst, &vlan)) != SEND_MBUF)) { if (j - first) { ret = tbase->aux->tx_pkt_l2(tbase, mbufs + first, j - first, out); ok += ret; @@ -83,7 +84,7 @@ int tx_pkt_ndp(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts if (likely(ret == 0)) { store_packet(tbase, mbufs[j]); mbuf->port = tbase->l3.reachable_port_id; - tx_ring_cti6(tbase, tbase->l3.ctrl_plane_ring, IP6_REQ_MAC_TO_MASTER, mbuf, tbase->l3.core_id, tbase->l3.task_id, &ip_dst); + tx_ring_cti6(tbase, tbase->l3.ctrl_plane_ring, IP6_REQ_MAC_TO_MASTER, mbuf, tbase->l3.core_id, tbase->l3.task_id, &ip_dst, vlan); } else { plog_err("Failed to get a mbuf from arp/nd mempool\n"); tx_drop(mbufs[j]); @@ -95,7 +96,7 @@ int tx_pkt_ndp(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&mbuf); if (likely(ret == 0)) { mbuf->port = tbase->l3.reachable_port_id; - tx_ring_cti6(tbase, tbase->l3.ctrl_plane_ring, IP6_REQ_MAC_TO_MASTER, mbuf, tbase->l3.core_id, tbase->l3.task_id, &ip_dst); + tx_ring_cti6(tbase, tbase->l3.ctrl_plane_ring, IP6_REQ_MAC_TO_MASTER, mbuf, tbase->l3.core_id, tbase->l3.task_id, &ip_dst, vlan); } else { plog_err("Failed to get a mbuf from arp/nd mempool\n"); // We still send the initial mbuf @@ -118,6 +119,7 @@ int tx_pkt_ndp(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts int tx_pkt_l3(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out) { uint32_t ip_dst; + uint16_t vlan; int first = 0, ret, ok = 0, rc; const struct port_queue *port_queue = &tbase->tx_params_hw.tx_port_queue[0]; struct rte_mbuf *arp_mbuf = NULL; // used when one need to send both an ARP and a mbuf @@ -127,7 +129,7 @@ int tx_pkt_l3(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, for (int j = 0; j < n_pkts; j++) { if ((out) && (out[j] >= OUT_HANDLED)) continue; - if (unlikely((rc = write_dst_mac(tbase, mbufs[j], &ip_dst, &time, tsc)) != SEND_MBUF)) { + if (unlikely((rc = write_dst_mac(tbase, mbufs[j], &ip_dst, &vlan, &time, tsc)) != SEND_MBUF)) { if (j - first) { ret = tbase->aux->tx_pkt_l2(tbase, mbufs + first, j - first, out); ok += ret; @@ -137,7 +139,7 @@ int tx_pkt_l3(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, case SEND_ARP_ND: // We re-use the mbuf - no need to create a arp_mbuf and delete the existing mbuf mbufs[j]->port = tbase->l3.reachable_port_id; - if (tx_ring_cti(tbase, tbase->l3.ctrl_plane_ring, IP4_REQ_MAC_TO_MASTER, mbufs[j], tbase->l3.core_id, tbase->l3.task_id, ip_dst) == 0) + if (tx_ring_cti(tbase, tbase->l3.ctrl_plane_ring, IP4_REQ_MAC_TO_MASTER, mbufs[j], tbase->l3.core_id, tbase->l3.task_id, ip_dst, vlan) == 0) update_arp_ndp_retransmit_timeout(&tbase->l3, time, 1000); else update_arp_ndp_retransmit_timeout(&tbase->l3, time, 100); @@ -147,7 +149,7 @@ int tx_pkt_l3(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&arp_mbuf); if (likely(ret == 0)) { arp_mbuf->port = tbase->l3.reachable_port_id; - if (tx_ring_cti(tbase, tbase->l3.ctrl_plane_ring, IP4_REQ_MAC_TO_MASTER, arp_mbuf, tbase->l3.core_id, tbase->l3.task_id, ip_dst) == 0) + if (tx_ring_cti(tbase, tbase->l3.ctrl_plane_ring, IP4_REQ_MAC_TO_MASTER, arp_mbuf, tbase->l3.core_id, tbase->l3.task_id, ip_dst, vlan) == 0) update_arp_ndp_retransmit_timeout(&tbase->l3, time, 1000); else update_arp_ndp_retransmit_timeout(&tbase->l3, time, 100); @@ -878,9 +880,10 @@ static inline int tx_ring_all(struct task_base *tbase, struct rte_ring *ring, ui return rte_ring_enqueue(ring, mbuf); } -int tx_ring_cti(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, uint32_t ip) +int tx_ring_cti(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, uint32_t ip, uint16_t vlan) { plogx_dbg("\tSending command %s with ip %d.%d.%d.%d to ring %p using mbuf %p, core %d and task %d - ring size now %d\n", actions_string[command], IP4(ip), ring, mbuf, core_id, task_id, rte_ring_free_count(ring)); + ctrl_ring_set_vlan(mbuf, vlan); int ret = tx_ring_all(tbase, ring, command, mbuf, core_id, task_id, ip); if (unlikely(ret != 0)) { plogx_dbg("\tFail to send command %s with ip %d.%d.%d.%d to ring %p using mbuf %p, core %d and task %d - ring size now %d\n", actions_string[command], IP4(ip), ring, mbuf, core_id, task_id, rte_ring_free_count(ring)); @@ -936,7 +939,7 @@ void tx_ring_route(struct task_base *tbase, struct rte_ring *ring, int add, stru } } -void tx_ring_cti6(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, struct ipv6_addr *ip) +void tx_ring_cti6(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, struct ipv6_addr *ip, uint16_t vlan) { int ret; plogx_dbg("\tSending command %s with ip "IPv6_BYTES_FMT" to ring %p using mbuf %p, core %d and task %d - ring size now %d\n", actions_string[command], IPv6_BYTES(ip->bytes), ring, mbuf, core_id, task_id, rte_ring_free_count(ring)); @@ -945,6 +948,7 @@ void tx_ring_cti6(struct task_base *tbase, struct rte_ring *ring, uint8_t comman } ctrl_ring_set_command_core_task_ip(mbuf, (core_id << 16) | (task_id << 8) | command); ctrl_ring_set_ipv6_addr(mbuf, ip); + ctrl_ring_set_vlan(mbuf, vlan); ret = rte_ring_enqueue(ring, mbuf); if (unlikely(ret != 0)) { diff --git a/VNFs/DPPD-PROX/tx_pkt.h b/VNFs/DPPD-PROX/tx_pkt.h index b54a2bef..0a71bcc3 100644 --- a/VNFs/DPPD-PROX/tx_pkt.h +++ b/VNFs/DPPD-PROX/tx_pkt.h @@ -26,10 +26,11 @@ struct task_base; struct prox_headroom { uint64_t command; + uint64_t data64; uint32_t ip; uint32_t prefix; uint32_t gateway_ip; - uint64_t data64; + uint16_t vlan; struct ipv6_addr ipv6_addr; } __attribute__((packed)); @@ -187,8 +188,20 @@ static inline struct ipv6_addr *ctrl_ring_get_ipv6_addr(struct rte_mbuf *mbuf) return &prox_headroom->ipv6_addr; } -int tx_ring_cti(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, uint32_t ip); -void tx_ring_cti6(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, struct ipv6_addr *ip); +static inline void ctrl_ring_set_vlan(struct rte_mbuf *mbuf, uint32_t udata16) +{ + struct prox_headroom *prox_headroom = (struct prox_headroom *)(rte_pktmbuf_mtod(mbuf, uint8_t*) - sizeof(struct prox_headroom)); + prox_headroom->vlan = udata16; +} + +static inline uint16_t ctrl_ring_get_vlan(struct rte_mbuf *mbuf) +{ + struct prox_headroom *prox_headroom = (struct prox_headroom *)(rte_pktmbuf_mtod(mbuf, uint8_t*) - sizeof(struct prox_headroom)); + return prox_headroom->vlan; +} + +int tx_ring_cti(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, uint32_t ip, uint16_t vlan); +void tx_ring_cti6(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint8_t core_id, uint8_t task_id, struct ipv6_addr *ip, uint16_t vlan); void tx_ring_ip(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, uint32_t ip); void tx_ring_ip6(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, struct ipv6_addr *ip); void tx_ring_ip6_data(struct task_base *tbase, struct rte_ring *ring, uint8_t command, struct rte_mbuf *mbuf, struct ipv6_addr *ip, uint64_t data); |