From 4ed5504a428fea4290cfe8594f5ff62edf50b878 Mon Sep 17 00:00:00 2001 From: Xavier Simonart Date: Mon, 1 Jun 2020 20:52:57 +0200 Subject: Added support for gateway ipv6 & cmd for sending unsollicited neighbor advertisement Change-Id: Iae35d3fa19ad7cf90d8c2e0c104b0e798ac34787 Signed-off-by: Xavier Simonart --- VNFs/DPPD-PROX/cmd_parser.c | 24 ++++++++++++++++++ VNFs/DPPD-PROX/packet_utils.c | 58 ++++++++++++++++++++++++++++++++----------- VNFs/DPPD-PROX/packet_utils.h | 1 + VNFs/DPPD-PROX/prox_args.c | 5 ++++ VNFs/DPPD-PROX/tx_pkt.c | 1 - 5 files changed, 73 insertions(+), 16 deletions(-) (limited to 'VNFs/DPPD-PROX') 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", " ", "Send igmp membership report for group ", parse_cmd_join_igmp}, {"leave igmp", " ", "Send igmp leave group", parse_cmd_leave_igmp}, + {"send unsollicited na", " ", "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]; -- cgit 1.2.3-korg