From 48f8c3d212644a33dd0abaaa1a0c71d4decaafdf Mon Sep 17 00:00:00 2001 From: Xavier Simonart Date: Mon, 24 Jun 2019 17:01:54 +0200 Subject: Add support for igmp and multicast Multicast can be enabled through configuration or through command line - Through configuration Add multicast=mcast_address (e.g. multicast=01:00:5e:01:02:03) in the port section - Through command line run enable multicast port_id mcast_address (e.g. enable multicast 1 01:00:5e:01:02:03) IGMP join message is sent unsollicited through command line: join igmp core_id task_id ip (e.g. join igmp 1 0 224.1.1.3) To enable swap answering IGMP Query (w/ IGMP Join) - Through configuration Add igmp ipv4=ip_address within the core/task section - Through command line join igmp core_id task_id ip (e.g. join igmp 1 0 224.1.1.3) (this will 1st initiate an unsollicated join, then answer any subsequent query) UDP/TCP packets received on a multicast address (224.0.0.0 => 239.255.255.255) are discarded To stop sending responses to IGMP query: leave igmp core_id task_id Change-Id: I3808ccabf3b38b5a1e10e1b044db63aa05bcd7b5 Signed-off-by: Xavier Simonart --- VNFs/DPPD-PROX/commands.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'VNFs/DPPD-PROX/commands.c') diff --git a/VNFs/DPPD-PROX/commands.c b/VNFs/DPPD-PROX/commands.c index 969dec39..a66f4888 100644 --- a/VNFs/DPPD-PROX/commands.c +++ b/VNFs/DPPD-PROX/commands.c @@ -246,6 +246,61 @@ static struct size_unit to_size_unit(uint64_t bytes) return ret; } +static int add_multicast_addr(uint8_t port_id, struct ether_addr *addr) +{ + unsigned int i; + int rc = 0; + + struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id]; + + if (port_cfg->nb_mc_addr >= NB_MCAST_ADDR) { + plog_err("Already reached maximum number (%d) of mcast addr on port %u\n", NB_MCAST_ADDR, port_id); + return -1; + } + for (i = 0; i < port_cfg->nb_mc_addr; i++) { + if (is_same_ether_addr(addr, &port_cfg->mc_addr[i])) { + plog_info("multicast address already added to port\n"); + return -1; + } + } + + ether_addr_copy(addr, &port_cfg->mc_addr[port_cfg->nb_mc_addr]); + if ((rc = rte_eth_dev_set_mc_addr_list(port_id, port_cfg->mc_addr, port_cfg->nb_mc_addr + 1)) != 0) { + plog_err("rte_eth_dev_set_mc_addr_list returns %d on port %u\n", rc, port_id); + return rc; + } + + port_cfg->nb_mc_addr++; + plog_info("rte_eth_dev_set_mc_addr_list(%d addr) on port %u\n", port_cfg->nb_mc_addr, port_id); + return rc; +} + +static int del_multicast_addr(uint8_t port_id, struct ether_addr *addr) +{ + unsigned int i; + int rc = 0; + + struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id]; + + for (i = 0; i < port_cfg->nb_mc_addr; i++) { + if (is_same_ether_addr(addr, &port_cfg->mc_addr[i])) { + // Copy last address to the slot to be deleted + ether_addr_copy(&port_cfg->mc_addr[port_cfg->nb_mc_addr-1], &port_cfg->mc_addr[i]); + + if ((rc = rte_eth_dev_set_mc_addr_list(port_id, port_cfg->mc_addr, port_cfg->nb_mc_addr - 1)) != 0) { + plog_err("rte_eth_dev_set_mc_addr_list returns %d on port %u\n", rc, port_id); + // When set failed, let restore the situation we were before calling the function... + ether_addr_copy(addr, &port_cfg->mc_addr[i]); + return rc; + } + port_cfg->nb_mc_addr--; + plog_info("rte_eth_dev_set_mc_addr_list(%d addr) on port %u\n", port_cfg->nb_mc_addr, port_id); + return 0; + } + } + plog_err("multicast address not found on port %u\n", port_id); + return -1; +} void cmd_mem_stats(void) { struct rte_malloc_socket_stats sock_stats; @@ -858,6 +913,9 @@ void cmd_portinfo(int port_id, char *dst, size_t max_len) dst += snprintf(dst, end - dst, "\tSocket: %u\n", port_cfg->socket); dst += snprintf(dst, end - dst, "\tPCI address: %s\n", port_cfg->pci_addr); dst += snprintf(dst, end - dst, "\tPromiscuous: %s\n", port_cfg->promiscuous? "yes" : "no"); + for (unsigned int i = 0; i < port_cfg->nb_mc_addr; i++) { + dst += snprintf(dst, end - dst, "\tmcast address: "MAC_BYTES_FMT"\n", MAC_BYTES(port_cfg->mc_addr[i].addr_bytes)); + } dst += snprintf(dst, end - dst, "\tNumber of RX/TX descriptors: %u/%u\n", port_cfg->n_rxd, port_cfg->n_txd); dst += snprintf(dst, end - dst, "\tNumber of RX/TX queues: %u/%u (max: %u/%u)\n", port_cfg->n_rxq, port_cfg->n_txq, port_cfg->max_rxq, port_cfg->max_txq); dst += snprintf(dst, end - dst, "\tMemory pools:\n"); @@ -899,6 +957,31 @@ void cmd_reset_port(uint8_t portid) } } +void cmd_multicast(uint8_t port_id, unsigned int val, struct ether_addr *mac) +{ + if (!port_is_active(port_id)) { + return; + } + struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id]; + if (val == 1) { + if (port_cfg->nb_mc_addr == 0) { + rte_eth_allmulticast_enable(port_id); + } + if (add_multicast_addr(port_id, mac) != 0) { + if (port_cfg->nb_mc_addr == 0) + rte_eth_allmulticast_disable(port_id); + } + } else if (val == 0) { + if (del_multicast_addr(port_id, mac) == 0) { + if (port_cfg->nb_mc_addr == 0) { + rte_eth_allmulticast_disable(port_id); + } + } + } else { + plog_err("Unexpected value in cmd_multicast on port %d\n", port_id); + } +} + void cmd_write_reg(uint8_t port_id, unsigned int id, unsigned int val) { if (!port_is_active(port_id)) { -- cgit 1.2.3-korg