diff options
-rw-r--r-- | VNFs/DPPD-PROX/cmd_parser.c | 7 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/commands.c | 4 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/display_pkt_len.c | 2 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/display_ports.c | 2 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/display_rings.c | 2 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/handle_master.c | 49 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/main.c | 6 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/packet_utils.c | 47 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/parse_utils.c | 66 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/parse_utils.h | 2 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_args.c | 17 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_port_cfg.c | 48 | ||||
-rw-r--r-- | VNFs/DPPD-PROX/prox_port_cfg.h | 14 |
13 files changed, 184 insertions, 82 deletions
diff --git a/VNFs/DPPD-PROX/cmd_parser.c b/VNFs/DPPD-PROX/cmd_parser.c index 1f2d5fc1..00027c47 100644 --- a/VNFs/DPPD-PROX/cmd_parser.c +++ b/VNFs/DPPD-PROX/cmd_parser.c @@ -995,12 +995,7 @@ static int parse_cmd_local_ip(const char *str, struct input *input) struct task_base *tbase = lcore_cfg[lcore_id].tasks_all[task_id]; uint32_t local_ip = ((ip[3] & 0xFF) << 24) | ((ip[2] & 0xFF) << 16) | ((ip[1] & 0xFF) << 8) | ((ip[0] & 0xFF) << 0); if (!task_is_mode_and_submode(lcore_id, task_id, "arp", "local")) { - if (!task_is_sub_mode(lcore_id, task_id, "l3")) { - plog_err("Core %u task %u is not in l3 mode\n", lcore_id, task_id); - } else { - plog_info("Setting local ip to %s\n", str); - task_set_local_ip(tbase, local_ip); - } + plog_err("Core %u task %u is not in arp mode\n", lcore_id, task_id); } else { plog_info("Setting local ip to %s\n", str); task_arp_set_local_ip(tbase, local_ip); diff --git a/VNFs/DPPD-PROX/commands.c b/VNFs/DPPD-PROX/commands.c index 1b406e47..c5ffed84 100644 --- a/VNFs/DPPD-PROX/commands.c +++ b/VNFs/DPPD-PROX/commands.c @@ -895,7 +895,7 @@ void cmd_portinfo(int port_id, char *dst, size_t max_len) dst += snprintf(dst, end - dst, "%2d:%10s; "MAC_BYTES_FMT"; %s\n", port_id, - port_cfg->name, + port_cfg->names[0], MAC_BYTES(port_cfg->eth_addr.addr_bytes), port_cfg->pci_addr); } @@ -909,7 +909,7 @@ void cmd_portinfo(int port_id, char *dst, size_t max_len) struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id]; dst += snprintf(dst, end - dst, "Port info for port %u\n", port_id); - dst += snprintf(dst, end - dst, "\tName: %s\n", port_cfg->name); + dst += snprintf(dst, end - dst, "\tName: %s\n", port_cfg->names[0]); dst += snprintf(dst, end - dst, "\tDriver: %s\n", port_cfg->driver_name); dst += snprintf(dst, end - dst, "\tMac address: "MAC_BYTES_FMT"\n", MAC_BYTES(port_cfg->eth_addr.addr_bytes)); dst += snprintf(dst, end - dst, "\tLink speed: %u Mbps\n", port_cfg->link_speed); diff --git a/VNFs/DPPD-PROX/display_pkt_len.c b/VNFs/DPPD-PROX/display_pkt_len.c index df34616a..83fbc655 100644 --- a/VNFs/DPPD-PROX/display_pkt_len.c +++ b/VNFs/DPPD-PROX/display_pkt_len.c @@ -81,7 +81,7 @@ static void display_pkt_len_draw_frame(struct screen_state *screen_state) const uint32_t port_id = port_disp[i]; display_column_print(port_col, i, "%4u", port_id); - display_column_print(name_col, i, "%8s", prox_port_cfg[port_id].name); + display_column_print(name_col, i, "%8s", prox_port_cfg[port_id].names[0]); display_column_print(type_col, i, "%7s", prox_port_cfg[port_id].short_name); } } diff --git a/VNFs/DPPD-PROX/display_ports.c b/VNFs/DPPD-PROX/display_ports.c index 79a5a2d7..891ff6f6 100644 --- a/VNFs/DPPD-PROX/display_ports.c +++ b/VNFs/DPPD-PROX/display_ports.c @@ -116,7 +116,7 @@ static void display_ports_draw_frame(struct screen_state *state) const uint32_t port_id = port_disp[i]; display_column_print(nb_col, i, "%u", port_id); - display_column_print(name_col, i, "%s", prox_port_cfg[port_id].name); + display_column_print(name_col, i, "%s", prox_port_cfg[port_id].names[0]); display_column_print(type_col, i, "%s", prox_port_cfg[port_id].short_name); } } diff --git a/VNFs/DPPD-PROX/display_rings.c b/VNFs/DPPD-PROX/display_rings.c index 618350e2..b3154237 100644 --- a/VNFs/DPPD-PROX/display_rings.c +++ b/VNFs/DPPD-PROX/display_rings.c @@ -68,7 +68,7 @@ static void display_rings_draw_frame(struct screen_state *state) int offset = 0; for (uint32_t j = 0; j < rs->nb_ports; j++) - offset += sprintf(name + offset, "%s", rs->port[j]->name); + offset += sprintf(name + offset, "%s", rs->port[j]->names[0]); } sc_val = (rs->ring->flags & RING_F_SC_DEQ) ? 'y' : 'n'; diff --git a/VNFs/DPPD-PROX/handle_master.c b/VNFs/DPPD-PROX/handle_master.c index 3be55810..b55db77e 100644 --- a/VNFs/DPPD-PROX/handle_master.c +++ b/VNFs/DPPD-PROX/handle_master.c @@ -167,16 +167,17 @@ void master_init_vdev(struct task_base *tbase, uint8_t port_id, uint8_t core_id, struct sockaddr_in dst, src; src.sin_family = AF_INET; - src.sin_addr.s_addr = prox_port_cfg[vdev_port].ip; src.sin_port = rte_cpu_to_be_16(PROX_PSEUDO_PKT_PORT); - - int fd = socket(AF_INET, SOCK_DGRAM, 0); - 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 (%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); + for (int vlan_id = 0; vlan_id < prox_port_cfg[vdev_port].n_vlans; vlan_id++) { + src.sin_addr.s_addr = prox_port_cfg[vdev_port].ip_addr[vlan_id].ip; + int fd = socket(AF_INET, SOCK_DGRAM, 0); + PROX_PANIC(fd < 0, "Failed to open socket(AF_INET, SOCK_DGRAM, 0)\n"); + prox_port_cfg[vdev_port].fds[vlan_id] = fd; + rc = bind(fd,(struct sockaddr *)&src, sizeof(struct sockaddr_in)); + 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++; } } @@ -783,6 +784,7 @@ static inline void handle_message(struct task_base *tbase, struct rte_mbuf *mbuf struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *); uint32_t ip = get_ip(mbuf); + vlan = ctrl_ring_get_vlan(mbuf); struct rte_ring *ring = task->ctrl_tx_rings[get_core(mbuf) * MAX_TASKS_PER_CORE + get_task(mbuf)]; // First check whether MAC address is not already in kernel MAC table. @@ -803,12 +805,23 @@ 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); - // 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)); + + int vlan_id; + for (vlan_id = 0; vlan_id < prox_port_cfg[vdev_port].n_vlans; vlan_id++) { + if (prox_port_cfg[vdev_port].vlan_tags[vlan_id] == vlan) + break; + } + if (vlan_id >= prox_port_cfg[vdev_port].n_vlans) { + // Tag not found + plogx_info("\tDid not send to TAP IP "IPv4_BYTES_FMT" as wrong VLAN %d\n", IPv4_BYTES(((uint8_t*)&ip)), vlan); + tx_drop(mbuf); + break; + } + int n = sendto(prox_port_cfg[vdev_port].fds[vlan_id], (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)); + 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].fds[vlan_id], 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); + 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].fds[vlan_id]); record_request(tbase, ip, port, ring); tx_drop(mbuf); @@ -1028,8 +1041,14 @@ static void handle_route_event(struct task_base *tbase) } int dpdk_vdev_port = -1; for (int i = 0; i< prox_rte_eth_dev_count_avail(); i++) { - if (strcmp(prox_port_cfg[i].name, interface_name) == 0) - dpdk_vdev_port = i; + for (int vlan_id = 0; vlan_id < prox_port_cfg[i].n_vlans; vlan_id++) { + if (strcmp(prox_port_cfg[i].names[vlan_id], interface_name) == 0) { + dpdk_vdev_port = i; + break; + } + } + if (dpdk_vdev_port != -1) + break; } if (dpdk_vdev_port != -1) { plogx_info("Received netlink message on tap interface %s for IP "IPv4_BYTES_FMT"/%d, Gateway "IPv4_BYTES_FMT"\n", interface_name, IP4(ip), dst_len, IP4(gw_ip)); diff --git a/VNFs/DPPD-PROX/main.c b/VNFs/DPPD-PROX/main.c index b9fe80a2..aeee288b 100644 --- a/VNFs/DPPD-PROX/main.c +++ b/VNFs/DPPD-PROX/main.c @@ -325,7 +325,7 @@ static void configure_if_rx_queues(struct task_args *targ, uint8_t socket) if (port_used_counter[if_port] > 1) { multiple_port_reference = true; port = &prox_port_cfg[if_port]; - PROX_PANIC((port->all_rx_queues), "Multiple queues defined in rx port, but all_rx_queues also set for port %s\n", port->name); + PROX_PANIC((port->all_rx_queues), "Multiple queues defined in rx port, but all_rx_queues also set for port %s\n", port->names[0]); } } // If only referenced once, it is possible that we want to use all queues @@ -338,7 +338,7 @@ static void configure_if_rx_queues(struct task_args *targ, uint8_t socket) if (port->all_rx_queues) { port_used_counter[if_port] = port->max_rxq; total_number_of_queues += port->max_rxq; - plog_info("\tall_rx_queues for Port %s: %u rx_queues will be applied\n", port->name, port_used_counter[if_port]); + plog_info("\tall_rx_queues for Port %s: %u rx_queues will be applied\n", port->names[0], port_used_counter[if_port]); } } } @@ -353,7 +353,7 @@ static void configure_if_rx_queues(struct task_args *targ, uint8_t socket) index ++; } port = &prox_port_cfg[i]; - plog_info("\t\tConfiguring task to use port %s with %u rx_queues\n", port->name, port_used_counter[i]); + plog_info("\t\tConfiguring task to use port %s with %u rx_queues\n", port->names[0], port_used_counter[i]); } } targ->nb_rxports = index; diff --git a/VNFs/DPPD-PROX/packet_utils.c b/VNFs/DPPD-PROX/packet_utils.c index bb942998..dcfd4f2e 100644 --- a/VNFs/DPPD-PROX/packet_utils.c +++ b/VNFs/DPPD-PROX/packet_utils.c @@ -135,7 +135,7 @@ void send_unsollicited_neighbour_advertisement(struct task_base *tbase) 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, prox_port_cfg[port_id].vlan_tag); + build_neighbour_advertisement(tbase->l3.tmaster, mbuf, &prox_port_cfg[port_id].eth_addr, &tbase->l3.local_ipv6, PROX_UNSOLLICITED, prox_port_cfg[port_id].vlan_tags[0]); tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out); TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1); } else { @@ -147,7 +147,7 @@ void send_unsollicited_neighbour_advertisement(struct task_base *tbase) 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, prox_port_cfg[port_id].vlan_tag); + build_neighbour_advertisement(tbase->l3.tmaster, mbuf, &prox_port_cfg[port_id].eth_addr, &tbase->l3.global_ipv6, PROX_UNSOLLICITED, prox_port_cfg[port_id].vlan_tags[0]); tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out); TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1); } else { @@ -169,7 +169,7 @@ static void send_router_sollicitation(struct task_base *tbase, struct task_args ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&mbuf); if (likely(ret == 0)) { mbuf->port = port_id; - build_router_sollicitation(mbuf, &prox_port_cfg[port_id].eth_addr, &targ->local_ipv6, prox_port_cfg[port_id].vlan_tag); + build_router_sollicitation(mbuf, &prox_port_cfg[port_id].eth_addr, &targ->local_ipv6, prox_port_cfg[port_id].vlan_tags[0]); tbase->aux->tx_ctrlplane_pkt(tbase, &mbuf, 1, &out); TASK_STATS_ADD_TX_NON_DP(&tbase->aux->stats, 1); } else { @@ -540,26 +540,27 @@ 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_addr[0].ip) && (targ->local_ipv4 != port->ip_addr[0].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_addr[0].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 && port->ip_addr[0].ip) && (targ->local_prefix != port->ip_addr[0].prefix)) { + PROX_PANIC(1, "local_ipv4 prefix in core section (%d) differs from port section (%d)\n", targ->local_prefix, port->ip_addr[0].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 (!port->ip_addr[0].ip) { + port->ip_addr[0].ip = targ->local_ipv4; + port->ip_addr[0].prefix = targ->local_prefix; + port->n_vlans = 1; + port->vlan_tags[0] = 0; + plog_info("Setting port local_ipv4 from core %d local_ipv4 to "IPv4_BYTES_FMT"\n", tbase->l3.reachable_port_id, IP4(rte_be_to_cpu_32(port->ip_addr[0].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); + for (int vlan_id = 0; vlan_id < port->n_vlans; vlan_id++) { + register_ip_to_ctrl_plane(tbase->l3.tmaster, rte_be_to_cpu_32(port->ip_addr[vlan_id].ip), tbase->l3.reachable_port_id, targ->lconf->id, targ->id); } if (strcmp(targ->route_table, "") != 0) { struct lpm4 *lpm; int ret; - PROX_PANIC(tbase->l3.local_ipv4 == 0, "missing local_ipv4 while route table is specified in L3 mode\n"); + PROX_PANIC(port->n_vlans == 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); @@ -582,10 +583,13 @@ void task_start_l3(struct task_base *tbase, struct task_args *targ) } plog_info("Using routing table %s in l3 mode, with %d gateways\n", targ->route_table, tbase->l3.nb_gws); - // Last but one "next_hop_index" is not a gateway but direct routes - tbase->l3.next_hops[tbase->l3.nb_gws].ip = 0; - ret = rte_lpm_add(tbase->l3.ipv4_lpm, targ->local_ipv4, targ->local_prefix, tbase->l3.nb_gws++); - PROX_PANIC(ret, "Failed to add local_ipv4 "IPv4_BYTES_FMT"/%d to lpm\n", IP4(tbase->l3.local_ipv4), targ->local_prefix); + // Last but one (x n_vlans) "next_hop_index" is not a gateway but direct routes + for (int vlan_id = 0; vlan_id < port->n_vlans; vlan_id++) { + tbase->l3.next_hops[tbase->l3.nb_gws].ip = 0; + ret = rte_lpm_add(tbase->l3.ipv4_lpm, port->ip_addr[vlan_id].ip, port->ip_addr[vlan_id].prefix, tbase->l3.nb_gws++); + PROX_PANIC(ret, "Failed to add local_ipv4 "IPv4_BYTES_FMT"/%d to lpm\n", IP4(port->ip_addr[vlan_id].ip), port->ip_addr[vlan_id].prefix); + } + // Last "next_hop_index" is default gw tbase->l3.next_hops[tbase->l3.nb_gws].ip = rte_bswap32(targ->gateway_ipv4); if (targ->gateway_ipv4) { @@ -648,11 +652,6 @@ void task_set_gateway_ip(struct task_base *tbase, uint32_t ip) tbase->flags &= ~FLAG_DST_MAC_KNOWN; } -void task_set_local_ip(struct task_base *tbase, uint32_t ip) -{ - tbase->l3.local_ipv4 = ip; -} - static void reset_arp_ndp_retransmit_timeout(struct l3_base *l3, uint32_t ip) { uint32_t idx; diff --git a/VNFs/DPPD-PROX/parse_utils.c b/VNFs/DPPD-PROX/parse_utils.c index 9ceb1c59..8d846fd3 100644 --- a/VNFs/DPPD-PROX/parse_utils.c +++ b/VNFs/DPPD-PROX/parse_utils.c @@ -846,6 +846,72 @@ int parse_task_set(struct core_task_set *cts, const char *str2) return 0; } +int parse_ip_set(struct ip4_subnet *list, const char *str2, uint32_t max_list) +{ + char str[MAX_STR_LEN_PROC]; + char *parts[MAX_STR_LEN_PROC]; + int n = 0, rc; + + if (parse_vars(str, sizeof(str), str2)) + return -1; + int n_parts = rte_strsplit(str, strlen(str), parts, MAX_STR_LEN_PROC, ','); + for (int i = 0; i < n_parts; i++) { + if ((rc = parse_ip4_and_prefix(&list[i], parts[i])) < 0) { + set_errf("Unable to parse ip4/prefix"); + return -1; + } + } + return 0; +} + +int parse_int_set(uint32_t *list, const char *str2, uint32_t max_list) +{ + char str[MAX_STR_LEN_PROC]; + char *parts[MAX_STR_LEN_PROC]; + uint32_t n = 0; + + if (parse_vars(str, sizeof(str), str2)) + return -1; + + int n_parts = rte_strsplit(str, strlen(str), parts, MAX_STR_LEN_PROC, ','); + for (int i = 0; i < n_parts; i++) { + char *cur_part = parts[i]; + char *sub_parts[3]; + int n_sub_parts = rte_strsplit(cur_part, strlen(cur_part), sub_parts, 3, '-'); + uint32_t n1, n2; + int ret = 0; + + if (n_sub_parts == 1) { + if (n >= max_list - 1) { + set_errf("Too many entries\n"); + return -1; + } + if (parse_int(&list[n], sub_parts[0])) + return -1; + n++; + } else if (n_sub_parts == 2) { + if (parse_int(&n1, sub_parts[0])) + return -1; + if (parse_int(&n2, sub_parts[1])) + return -1; + if (n + n2 - n1 >= max_list) { + set_errf("Too many entries\n"); + return -1; + } + for (uint32_t j = n1; j < n2; j++) { + list[n++] = j; + } + } else if (n_sub_parts >= 3) { + set_errf("Multiple '-' characters in range syntax found"); + return -1; + } else { + set_errf("Invalid list syntax"); + return -1; + } + } + return 0; +} + int parse_list_set(uint32_t *list, const char *str2, uint32_t max_list) { char str[MAX_STR_LEN_PROC]; diff --git a/VNFs/DPPD-PROX/parse_utils.h b/VNFs/DPPD-PROX/parse_utils.h index 5671e377..03c03188 100644 --- a/VNFs/DPPD-PROX/parse_utils.h +++ b/VNFs/DPPD-PROX/parse_utils.h @@ -64,6 +64,8 @@ int parse_bool(uint32_t* val, const char *str); int parse_flag(uint32_t* val, uint32_t flag, const char *str); int parse_list_set(uint32_t *list, const char *str, uint32_t max_limit); +int parse_ip_set(struct ip4_subnet *list, const char *str2, uint32_t max_list); +int parse_int_set(uint32_t *list, const char *str2, uint32_t max_list); int parse_task_set(struct core_task_set *val, const char *str); diff --git a/VNFs/DPPD-PROX/prox_args.c b/VNFs/DPPD-PROX/prox_args.c index b16ce7bb..d6c1639d 100644 --- a/VNFs/DPPD-PROX/prox_args.c +++ b/VNFs/DPPD-PROX/prox_args.c @@ -38,6 +38,7 @@ #include "defines.h" #include "prox_ipv6.h" #include "prox_compat.h" +#include "ip_subnet.h" #define MAX_RTE_ARGV 64 #define MAX_ARG_LEN 64 @@ -531,7 +532,7 @@ static int get_port_cfg(unsigned sindex, char *str, void *data) } else if (STR_EQ(str, "name")) { uint32_t val; - prox_strncpy(cfg->name, pkey, MAX_NAME_SIZE); + prox_strncpy(cfg->names[0], pkey, MAX_NAME_SIZE); PROX_ASSERT(cur_if < PROX_MAX_PORTS); return add_port_name(cur_if, pkey); } @@ -575,15 +576,11 @@ static int get_port_cfg(unsigned sindex, char *str, void *data) cfg->lsc_val = val; } else if (STR_EQ(str, "local ipv4")) { - 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; + if (parse_ip_set(cfg->ip_addr, pkey, PROX_MAX_VLAN_TAGS) != 0) { + cfg->ip_addr[0].ip = 24; + return parse_ip(&cfg->ip_addr[0].ip, pkey); } + return 0; } else if (STR_EQ(str, "vdev")) { prox_strncpy(cfg->vdev, pkey, MAX_NAME_SIZE); @@ -619,7 +616,7 @@ static int get_port_cfg(unsigned sindex, char *str, void *data) } else if (STR_EQ(str, "vlan tag")) { - return parse_int(&cfg->vlan_tag, pkey); + return parse_int_set(cfg->vlan_tags, pkey, sizeof(cfg->vlan_tags) / sizeof(cfg->vlan_tags[0])); } else if (STR_EQ(str, "vlan")) { #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1) diff --git a/VNFs/DPPD-PROX/prox_port_cfg.c b/VNFs/DPPD-PROX/prox_port_cfg.c index 451555a9..859c4372 100644 --- a/VNFs/DPPD-PROX/prox_port_cfg.c +++ b/VNFs/DPPD-PROX/prox_port_cfg.c @@ -214,6 +214,12 @@ void init_rte_dev(int use_dummy_devices) continue; } struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id]; + + prox_port_cfg[port_id].n_vlans = 0; + while ((prox_port_cfg[port_id].n_vlans < PROX_MAX_VLAN_TAGS) && (prox_port_cfg[port_id].vlan_tags[prox_port_cfg[port_id].n_vlans])) { + prox_port_cfg[port_id].n_vlans++; + } + if (port_cfg->vdev[0]) { char name[MAX_NAME_SIZE], tap[MAX_NAME_SIZE]; snprintf(tap, MAX_NAME_SIZE, "net_tap%d", port_id); @@ -231,20 +237,30 @@ void init_rte_dev(int use_dummy_devices) 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; + prox_port_cfg[vdev_port_id].n_vlans = prox_port_cfg[port_id].n_vlans; - if (prox_port_cfg[port_id].vlan_tag) { + for (uint32_t tag_id = 0; tag_id < prox_port_cfg[port_id].n_vlans; tag_id++) { + prox_port_cfg[vdev_port_id].vlan_tags[tag_id] = prox_port_cfg[port_id].vlan_tags[tag_id]; char command[1024]; - snprintf(prox_port_cfg[vdev_port_id].name, MAX_NAME_SIZE, "%s_%d", port_cfg->vdev, prox_port_cfg[port_id].vlan_tag); - sprintf(command, "ip link add link %s name %s type vlan id %d", port_cfg->vdev, prox_port_cfg[vdev_port_id].name, prox_port_cfg[port_id].vlan_tag); + snprintf(prox_port_cfg[vdev_port_id].names[tag_id], MAX_NAME_SIZE, "%s_%d", port_cfg->vdev, prox_port_cfg[port_id].vlan_tags[tag_id]); + sprintf(command, "ip link add link %s name %s type vlan id %d", port_cfg->vdev, prox_port_cfg[vdev_port_id].names[tag_id], prox_port_cfg[port_id].vlan_tags[tag_id]); system(command); - plog_info("Running %s\n", command); - plog_info("Using vlan tag %d - added device %s\n", prox_port_cfg[port_id].vlan_tag, prox_port_cfg[vdev_port_id].name); - } else - strncpy(prox_port_cfg[vdev_port_id].name, port_cfg->vdev, MAX_NAME_SIZE); + plog_info("\tRunning %s\n", command); + plog_info("\tUsing vlan tag %d - added device %s\n", prox_port_cfg[port_id].vlan_tags[tag_id], prox_port_cfg[vdev_port_id].names[tag_id]); + } + if (prox_port_cfg[port_id].n_vlans == 0) { + strncpy(prox_port_cfg[vdev_port_id].names[0], port_cfg->vdev, MAX_NAME_SIZE); + prox_port_cfg[vdev_port_id].n_vlans = 1; + prox_port_cfg[vdev_port_id].vlan_tags[0] = 0; + } 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[vdev_port_id].prefix = prox_port_cfg[port_id].prefix; + uint32_t i = 0; + while ((i < PROX_MAX_VLAN_TAGS) && (prox_port_cfg[port_id].ip_addr[i].ip)) { + prox_port_cfg[vdev_port_id].ip_addr[i].ip = rte_be_to_cpu_32(prox_port_cfg[port_id].ip_addr[i].ip); + prox_port_cfg[vdev_port_id].ip_addr[i].prefix = prox_port_cfg[port_id].ip_addr[i].prefix; + i++; + } 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 @@ -255,6 +271,10 @@ void init_rte_dev(int use_dummy_devices) } else memcpy(&prox_port_cfg[vdev_port_id].eth_addr, &prox_port_cfg[port_id].eth_addr, sizeof(prox_port_cfg[port_id].eth_addr)); } + if (prox_port_cfg[port_id].n_vlans == 0) { + prox_port_cfg[port_id].n_vlans = 1; + prox_port_cfg[port_id].vlan_tags[0] = 0; + } } nb_ports = prox_rte_eth_dev_count_avail(); /* get available ports configuration */ @@ -425,7 +445,7 @@ uint8_t init_rte_ring_dev(void) struct rte_ring* tx_ring = rte_ring_lookup(port_cfg->tx_ring); PROX_PANIC(tx_ring == NULL, "Ring %s not found for port %d!\n", port_cfg->tx_ring, port_id); - int ret = rte_eth_from_rings(port_cfg->name, &rx_ring, 1, &tx_ring, 1, rte_socket_id()); + int ret = rte_eth_from_rings(port_cfg->names[0], &rx_ring, 1, &tx_ring, 1, rte_socket_id()); PROX_PANIC(ret != 0, "Failed to create eth_dev from rings for port %d\n", port_id); port_cfg->port_conf.intr_conf.lsc = 0; /* Link state interrupt not supported for ring-backed ports */ @@ -443,7 +463,7 @@ static void print_port_capa(struct prox_port_cfg *port_cfg) port_id = port_cfg - prox_port_cfg; plog_info("\t*** Initializing port %u ***\n", port_id); - plog_info("\t\tPort name is set to %s\n", port_cfg->name); + plog_info("\t\tPort name is set to %s\n", port_cfg->names[0]); plog_info("\t\tPort max RX/TX queue is %u/%u\n", port_cfg->max_rxq, port_cfg->max_txq); plog_info("\t\tPort driver is %s\n", port_cfg->driver_name); #if RTE_VERSION >= RTE_VERSION_NUM(16,4,0,0) @@ -802,8 +822,10 @@ 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) && (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); + if (prox_port_cfg[port_id].is_vdev) { + for (int vlan_id = 0; vlan_id < prox_port_cfg[port_id].n_vlans; vlan_id++) { + set_ip_address(prox_port_cfg[port_id].names[vlan_id], &prox_port_cfg[port_id].ip_addr[vlan_id].ip, prox_port_cfg[port_id].ip_addr[vlan_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 f5929a72..738ce86a 100644 --- a/VNFs/DPPD-PROX/prox_port_cfg.h +++ b/VNFs/DPPD-PROX/prox_port_cfg.h @@ -28,12 +28,14 @@ #include "prox_compat.h" #include "prox_globals.h" +#include "ip_subnet.h" enum addr_type {PROX_PORT_MAC_HW, PROX_PORT_MAC_SET, PROX_PORT_MAC_RAND}; #define IPV4_CKSUM 1 #define UDP_CKSUM 2 #define NB_MCAST_ADDR 16 +#define PROX_MAX_VLAN_TAGS 256 struct prox_port_cfg { struct rte_mempool *pool[32]; /* Rx/Tx mempool */ @@ -55,7 +57,7 @@ struct prox_port_cfg { uint32_t mtu; enum addr_type type; prox_rte_ether_addr eth_addr; /* port MAC address */ - char name[MAX_NAME_SIZE]; + char names[PROX_MAX_VLAN_TAGS][MAX_NAME_SIZE]; char vdev[MAX_NAME_SIZE]; char short_name[MAX_NAME_SIZE]; char driver_name[MAX_NAME_SIZE]; @@ -82,12 +84,12 @@ struct prox_port_cfg { uint8_t available; prox_rte_ether_addr mc_addr[NB_MCAST_ADDR]; int dpdk_mapping; - uint32_t ip; - int fd; - uint32_t vlan_tag; - uint8_t prefix; + struct ip4_subnet ip_addr[PROX_MAX_VLAN_TAGS]; + int fds[PROX_MAX_VLAN_TAGS]; + uint32_t vlan_tags[PROX_MAX_VLAN_TAGS]; uint8_t is_vdev; - uint8_t all_rx_queues; + uint8_t all_rx_queues; + uint16_t n_vlans; }; extern rte_atomic32_t lsc; |