summaryrefslogtreecommitdiffstats
path: root/VNFs/DPPD-PROX/packet_utils.c
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/DPPD-PROX/packet_utils.c
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/DPPD-PROX/packet_utils.c')
-rw-r--r--VNFs/DPPD-PROX/packet_utils.c33
1 files changed, 24 insertions, 9 deletions
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);