summaryrefslogtreecommitdiffstats
path: root/VNFs
diff options
context:
space:
mode:
authorXavier Simonart <xavier.simonart@intel.com>2020-05-29 00:06:45 +0200
committerXavier Simonart <xavier.simonart@intel.com>2020-05-29 23:51:04 +0200
commit33d5f47e781c6986232378b7f8cadd17ac8894fe (patch)
tree3d120cd0d22dfae25dd01a372b1ecfb49ee970e8 /VNFs
parent51fd77bfea70da57af93390e1992b16022e2c88f (diff)
VLAN support with vdev devices + few other changes
- vdev devices now support VLAN. - kernel tap device can be configured with a netmask (/24 was always used in previous version). - when sending a (fake) packet to the kernel, this packet will now not be routed by the kernel (i.e. it will leave through the interface configured by PROX). This might change in the futture when PROX supports multiple VLANs per port. But today it prevents ARP being sent on management interfaces. - Log error in case kernel unable to send packet. - Added support for comments (';') in lua sections. - Prevent duplication of local_ipv4 - should now be configured in port section local_ipv4 in core section still supported Change-Id: I8f9a40fe6ad6f3013ff91b58b44627c7f34081e6 Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
Diffstat (limited to 'VNFs')
-rw-r--r--VNFs/DPPD-PROX/arp.h76
-rw-r--r--VNFs/DPPD-PROX/cfgfile.c5
-rw-r--r--VNFs/DPPD-PROX/handle_arp.c6
-rw-r--r--VNFs/DPPD-PROX/handle_master.c79
-rw-r--r--VNFs/DPPD-PROX/packet_utils.c33
-rw-r--r--VNFs/DPPD-PROX/packet_utils.h4
-rw-r--r--VNFs/DPPD-PROX/parse_utils.c12
-rw-r--r--VNFs/DPPD-PROX/parse_utils.h1
-rw-r--r--VNFs/DPPD-PROX/prox_args.c12
-rw-r--r--VNFs/DPPD-PROX/prox_port_cfg.c28
-rw-r--r--VNFs/DPPD-PROX/prox_port_cfg.h2
-rw-r--r--VNFs/DPPD-PROX/tx_pkt.c20
-rw-r--r--VNFs/DPPD-PROX/tx_pkt.h19
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(&ether_hdr->d_addr.addr_bytes, &mac_bcast, 6);
+ memcpy(&ether_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);