diff options
author | Xavier Simonart <xavier.simonart@intel.com> | 2020-07-10 12:59:40 +0200 |
---|---|---|
committer | Xavier Simonart <xavier.simonart@intel.com> | 2020-09-21 10:35:03 +0200 |
commit | 9a1e1e9336b39178362c6ccadd4a9716f865047f (patch) | |
tree | ddcf3543c1145183e37563597b7848dc675959e8 /VNFs | |
parent | dcbc010d7e50d5d42ce5ecba9b6a2234998e7c88 (diff) |
Added support for multiple vlans in ipv4 vdev mode
When the following conditions are met:
- ipv4
- vdev enabled
Then multiple vlans are supported.
Multiple vlans can be configured using the vlan_tag option within the port section of the config file.
Multiple (different) local_ipv4/prefix must then also be configured within the same section.
Note that for ipv6 multiple vlans are not supported (yet)
Also, when vdev is not enabled, multiple vlans are also not (yet) supported.
Change-Id: I38b6cd98ff2a0f484d1bf0910b15413ba21ae6d6
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
Diffstat (limited to 'VNFs')
-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; |