summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--VNFs/DPPD-PROX/cmd_parser.c24
-rw-r--r--VNFs/DPPD-PROX/packet_utils.c58
-rw-r--r--VNFs/DPPD-PROX/packet_utils.h1
-rw-r--r--VNFs/DPPD-PROX/prox_args.c5
-rw-r--r--VNFs/DPPD-PROX/tx_pkt.c1
5 files changed, 73 insertions, 16 deletions
diff --git a/VNFs/DPPD-PROX/cmd_parser.c b/VNFs/DPPD-PROX/cmd_parser.c
index 51a71f48..1f2d5fc1 100644
--- a/VNFs/DPPD-PROX/cmd_parser.c
+++ b/VNFs/DPPD-PROX/cmd_parser.c
@@ -2162,6 +2162,29 @@ static int parse_cmd_join_igmp(const char *str, struct input *input)
return 0;
}
+static int parse_cmd_send_unsollicited_na(const char *str, struct input *input)
+{
+ unsigned lcores[RTE_MAX_LCORE], lcore_id, task_id, nb_cores;
+
+ if (parse_cores_task(str, lcores, &task_id, &nb_cores))
+ return -1;
+
+ if (cores_task_are_valid(lcores, task_id, nb_cores)) {
+ for (unsigned int i = 0; i < nb_cores; i++) {
+ lcore_id = lcores[i];
+
+ if (!task_is_sub_mode(lcore_id, task_id, "ndp")) {
+ plog_err("Core %u task %u is not running ndp\n", lcore_id, task_id);
+ }
+ else {
+ struct task_base *tbase = lcore_cfg[lcore_id].tasks_all[task_id];
+ send_unsollicited_neighbour_advertisement(tbase);
+ }
+ }
+ }
+ return 0;
+}
+
static int parse_cmd_rx_tx_info(const char *str, struct input *input)
{
if (strcmp(str, "") != 0) {
@@ -2301,6 +2324,7 @@ static struct cmd_str cmd_strings[] = {
{"version", "", "Show version", parse_cmd_version},
{"join igmp", "<core_id> <task_id> <ip>", "Send igmp membership report for group <ip>", parse_cmd_join_igmp},
{"leave igmp", "<core_id> <task_id>", "Send igmp leave group", parse_cmd_leave_igmp},
+ {"send unsollicited na", "<core_id> <task_id>", "Send Unsollicited Neighbor Advertisement", parse_cmd_send_unsollicited_na},
{0,0,0,0},
};
diff --git a/VNFs/DPPD-PROX/packet_utils.c b/VNFs/DPPD-PROX/packet_utils.c
index 70d5c02f..a12281d2 100644
--- a/VNFs/DPPD-PROX/packet_utils.c
+++ b/VNFs/DPPD-PROX/packet_utils.c
@@ -142,20 +142,38 @@ static inline struct ipv6_addr *find_ip6(prox_rte_ether_hdr *pkt, uint16_t len,
return NULL;
}
-static void send_unsollicited_neighbour_advertisement(struct task_base *tbase, struct task_args *targ)
+void send_unsollicited_neighbour_advertisement(struct task_base *tbase)
{
int ret;
uint8_t out = 0, port_id = tbase->l3.reachable_port_id;
- struct rte_mbuf *mbuf;
-
- 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, &targ->local_ipv6, PROX_UNSOLLICITED);
- tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out);
- TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1);
- } else {
- plog_err("Failed to get a mbuf from arp/ndp mempool\n");
+ struct rte_mbuf *mbuf = NULL;
+
+ if (memcmp(&tbase->l3.local_ipv6, &null_addr, 16) != 0) {
+ 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);
+ tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out);
+ TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1);
+ } else {
+ plog_err("Failed to get a mbuf from arp/ndp mempool\n");
+ return;
+ }
+ }
+ if (memcmp(&tbase->l3.global_ipv6, &null_addr, 16) != 0) {
+ 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);
+ tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out);
+ TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1);
+ } else {
+ plog_err("Failed to get a mbuf from arp/ndp mempool\n");
+ return;
+ }
+ }
+ if (mbuf == NULL) {
+ plog_err("No neighbor advertisement sent as no local or global ipv6\n");
}
}
@@ -363,18 +381,27 @@ int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv
return SEND_MBUF;
}
struct l3_base *l3 = &(tbase->l3);
+
+ // Configure source IP
if (memcmp(&l3->local_ipv6, ip_dst, 8) == 0) {
// Same prefix as local -> use local
used_ip_src = &l3->local_ipv6;
- } else if (memcmp(&l3->global_ipv6 , &null_addr, 16) != 0) {
+ } else if (memcmp(&l3->global_ipv6 , ip_dst, 8) == 0) {
+ // Same prefix as global -> use global
+ used_ip_src = &l3->global_ipv6;
+ } else if (memcmp(&l3->gw.ip6 , &null_addr, sizeof(struct ipv6_addr)) != 0) {
+ used_ip_src = &l3->global_ipv6;
+ memcpy(ip_dst, &l3->gw.ip6, sizeof(struct ipv6_addr));
+ } else if (memcmp(&l3->global_ipv6 , &null_addr, sizeof(struct ipv6_addr)) != 0) {
// Global IP is defined -> use it
used_ip_src = &l3->global_ipv6;
} else {
plog_info("Error as trying to send a packet to "IPv6_BYTES_FMT" using "IPv6_BYTES_FMT" (local)\n", IPv6_BYTES(ip_dst->bytes), IPv6_BYTES(l3->local_ipv6.bytes));
return DROP_MBUF;
}
-
memcpy(pkt_src_ip6, used_ip_src, sizeof(struct ipv6_addr));
+
+ // Configure dst mac
if (likely(l3->n_pkts < 4)) {
for (unsigned int idx = 0; idx < l3->n_pkts; idx++) {
if (memcmp(ip_dst, &l3->optimized_arp_table[idx].ip6, sizeof(struct ipv6_addr)) == 0) {
@@ -504,6 +531,7 @@ void task_init_l3(struct task_base *tbase, struct task_args *targ)
targ->lconf->ctrl_func_p[targ->task] = handle_ctrl_plane_pkts;
targ->lconf->ctrl_timeout = freq_to_tsc(targ->ctrl_freq);
tbase->l3.gw.ip = rte_cpu_to_be_32(targ->gateway_ipv4);
+ memcpy(&tbase->l3.gw.ip6, &targ->gateway_ipv6, sizeof(struct ipv6_addr));
tbase->flags |= TASK_L3;
tbase->l3.core_id = targ->lconf->id;
tbase->l3.task_id = targ->id;
@@ -588,7 +616,7 @@ void task_start_l3(struct task_base *tbase, struct task_args *targ)
// Create IPv6 addr if none were configured
if (targ->flags & TASK_ARG_NDP) {
- if (!memcmp(&targ->local_ipv6, &null_addr, 16)) {
+ if (!memcmp(&targ->local_ipv6, &null_addr, sizeof(struct ipv6_addr))) {
set_link_local(&targ->local_ipv6);
set_EUI(&targ->local_ipv6, &port->eth_addr);
}
@@ -626,7 +654,7 @@ void task_start_l3(struct task_base *tbase, struct task_args *targ)
}
if ((targ->flags & TASK_ARG_NDP) && (targ->flags & TASK_ARG_SEND_NA_AT_STARTUP)) {
plog_info("Sending unsollicited Neighbour Advertisement\n");
- send_unsollicited_neighbour_advertisement(tbase, targ);
+ send_unsollicited_neighbour_advertisement(tbase);
}
}
diff --git a/VNFs/DPPD-PROX/packet_utils.h b/VNFs/DPPD-PROX/packet_utils.h
index e1b262dc..ce54a89e 100644
--- a/VNFs/DPPD-PROX/packet_utils.h
+++ b/VNFs/DPPD-PROX/packet_utils.h
@@ -83,6 +83,7 @@ int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv
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);
+void send_unsollicited_neighbour_advertisement(struct task_base *tbase);
static inline void update_arp_ndp_retransmit_timeout(struct l3_base *l3, uint64_t *ptr, uint32_t base)
{
diff --git a/VNFs/DPPD-PROX/prox_args.c b/VNFs/DPPD-PROX/prox_args.c
index 3e3e41ba..b16ce7bb 100644
--- a/VNFs/DPPD-PROX/prox_args.c
+++ b/VNFs/DPPD-PROX/prox_args.c
@@ -1522,6 +1522,11 @@ static int get_core_cfg(unsigned sindex, char *str, void *data)
}
return 0;
}
+ if (STR_EQ(str, "gateway ipv6")) { /* Gateway IP address used when generating */
+ if ((targ->flags & TASK_ARG_NDP) == 0)
+ plog_warn("gateway ipv6 configured but NDP sub mode not enabled\n");
+ return parse_ip6(&targ->gateway_ipv6, pkey);
+ }
if (STR_EQ(str, "local ipv4")) { /* source IP address to be used for packets */
struct ip4_subnet cidr;
if (parse_ip4_and_prefix(&cidr, pkey) != 0) {
diff --git a/VNFs/DPPD-PROX/tx_pkt.c b/VNFs/DPPD-PROX/tx_pkt.c
index f45516ec..d93c5fba 100644
--- a/VNFs/DPPD-PROX/tx_pkt.c
+++ b/VNFs/DPPD-PROX/tx_pkt.c
@@ -61,7 +61,6 @@ void store_packet(struct task_base *tbase, struct rte_mbuf *mbuf)
int tx_pkt_ndp(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts, uint8_t *out)
{
- // TODO NDP
struct ipv6_addr ip_dst;
int first = 0, ret, ok = 0, rc;
const struct port_queue *port_queue = &tbase->tx_params_hw.tx_port_queue[0];