From b34801d1aa2e35f72203595c755aeb1b161724e8 Mon Sep 17 00:00:00 2001 From: Xiaolong Ye Date: Mon, 12 Aug 2019 11:06:30 +0800 Subject: [PATCH] kni: support allmulticast mode set This patch adds support to allow users enable/disable allmulticast mode for kni interface. This requirement comes from bugzilla 312, more details can refer to: https://bugs.dpdk.org/show_bug.cgi?id=312 Bugzilla ID: 312 Signed-off-by: Xiaolong Ye Acked-by: Ferruh Yigit --- .../prog_guide/kernel_nic_interface.rst | 9 ++++++ kernel/linux/kni/kni_net.c | 27 +++++++++++----- .../linux/eal/include/rte_kni_common.h | 2 ++ lib/librte_kni/rte_kni.c | 31 ++++++++++++++++++- lib/librte_kni/rte_kni.h | 3 ++ 5 files changed, 64 insertions(+), 8 deletions(-) diff --git a/doc/guides/prog_guide/kernel_nic_interface.rst b/doc/guides/prog_guide/kernel_nic_interface.rst index 38369b30e0..2fd58e1175 100644 --- a/doc/guides/prog_guide/kernel_nic_interface.rst +++ b/doc/guides/prog_guide/kernel_nic_interface.rst @@ -235,6 +235,15 @@ application functions: will be called which calls ``rte_eth_promiscuous_()`` on the specified ``port_id``. +``config_allmulticast``: + + Called when the user changes the allmulticast state of the KNI interface. + For example, when the user runs ``ifconfig [-]allmulti``. If the + user sets this callback function to NULL, but sets the ``port_id`` field to + a value other than -1, a default callback handler in the rte_kni library + ``kni_config_allmulticast()`` will be called which calls + ``rte_eth_allmulticast_()`` on the specified ``port_id``. + In order to run these callbacks, the application must periodically call the ``rte_kni_handle_request()`` function. Any user callback function registered will be called directly from ``rte_kni_handle_request()`` so diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c index 7bd3a9f1ea..f25b1277bd 100644 --- a/kernel/linux/kni/kni_net.c +++ b/kernel/linux/kni/kni_net.c @@ -617,18 +617,31 @@ kni_net_change_mtu(struct net_device *dev, int new_mtu) } static void -kni_net_set_promiscusity(struct net_device *netdev, int flags) +kni_net_change_rx_flags(struct net_device *netdev, int flags) { struct rte_kni_request req; struct kni_dev *kni = netdev_priv(netdev); memset(&req, 0, sizeof(req)); - req.req_id = RTE_KNI_REQ_CHANGE_PROMISC; - if (netdev->flags & IFF_PROMISC) - req.promiscusity = 1; - else - req.promiscusity = 0; + if (flags & IFF_ALLMULTI) { + req.req_id = RTE_KNI_REQ_CHANGE_ALLMULTI; + + if (netdev->flags & IFF_ALLMULTI) + req.allmulti = 1; + else + req.allmulti = 0; + } + + if (flags & IFF_PROMISC) { + req.req_id = RTE_KNI_REQ_CHANGE_PROMISC; + + if (netdev->flags & IFF_PROMISC) + req.promiscusity = 1; + else + req.promiscusity = 0; + } + kni_net_process_request(kni, &req); } @@ -731,7 +744,7 @@ static const struct net_device_ops kni_net_netdev_ops = { .ndo_open = kni_net_open, .ndo_stop = kni_net_release, .ndo_set_config = kni_net_config, - .ndo_change_rx_flags = kni_net_set_promiscusity, + .ndo_change_rx_flags = kni_net_change_rx_flags, .ndo_start_xmit = kni_net_tx, .ndo_change_mtu = kni_net_change_mtu, .ndo_tx_timeout = kni_net_tx_timeout, diff --git a/lib/librte_eal/linux/eal/include/rte_kni_common.h b/lib/librte_eal/linux/eal/include/rte_kni_common.h index 37d9ee8f0f..b51fe27bd7 100644 --- a/lib/librte_eal/linux/eal/include/rte_kni_common.h +++ b/lib/librte_eal/linux/eal/include/rte_kni_common.h @@ -31,6 +31,7 @@ enum rte_kni_req_id { RTE_KNI_REQ_CFG_NETWORK_IF, RTE_KNI_REQ_CHANGE_MAC_ADDR, RTE_KNI_REQ_CHANGE_PROMISC, + RTE_KNI_REQ_CHANGE_ALLMULTI, RTE_KNI_REQ_MAX, }; @@ -45,6 +46,7 @@ struct rte_kni_request { uint8_t if_up; /**< 1: interface up, 0: interface down */ uint8_t mac_addr[6]; /**< MAC address for interface */ uint8_t promiscusity;/**< 1: promisc mode enable, 0: disable */ + uint8_t allmulti; /**< 1: all-multicast mode enable, 0: disable */ }; int32_t result; /**< Result for processing request */ } __attribute__((__packed__)); diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c index 04806ebb40..0f36485089 100644 --- a/lib/librte_kni/rte_kni.c +++ b/lib/librte_kni/rte_kni.c @@ -496,6 +496,26 @@ kni_config_promiscusity(uint16_t port_id, uint8_t to_on) return ret; } +/* default callback for request of configuring allmulticast mode */ +static int +kni_config_allmulticast(uint16_t port_id, uint8_t to_on) +{ + if (!rte_eth_dev_is_valid_port(port_id)) { + RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id); + return -EINVAL; + } + + RTE_LOG(INFO, KNI, "Configure allmulticast mode of %d to %d\n", + port_id, to_on); + + if (to_on) + rte_eth_allmulticast_enable(port_id); + else + rte_eth_allmulticast_disable(port_id); + + return 0; +} + int rte_kni_handle_request(struct rte_kni *kni) { @@ -543,6 +563,14 @@ rte_kni_handle_request(struct rte_kni *kni) req->result = kni_config_promiscusity( kni->ops.port_id, req->promiscusity); break; + case RTE_KNI_REQ_CHANGE_ALLMULTI: /* Change ALLMULTICAST MODE */ + if (kni->ops.config_allmulticast) + req->result = kni->ops.config_allmulticast( + kni->ops.port_id, req->allmulti); + else if (kni->ops.port_id != UINT16_MAX) + req->result = kni_config_allmulticast( + kni->ops.port_id, req->allmulti); + break; default: RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id); req->result = -EINVAL; @@ -692,7 +720,8 @@ kni_check_request_register(struct rte_kni_ops *ops) if (ops->change_mtu == NULL && ops->config_network_if == NULL && ops->config_mac_address == NULL - && ops->config_promiscusity == NULL) + && ops->config_promiscusity == NULL + && ops->config_allmulticast == NULL) return KNI_REQ_NO_REGISTER; return KNI_REQ_REGISTERED; diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h index 5699a64432..f6b66c33de 100644 --- a/lib/librte_kni/rte_kni.h +++ b/lib/librte_kni/rte_kni.h @@ -48,6 +48,9 @@ struct rte_kni_ops { /* Pointer to function of configuring promiscuous mode */ int (*config_promiscusity)(uint16_t port_id, uint8_t to_on); + + /* Pointer to function of configuring allmulticast mode */ + int (*config_allmulticast)(uint16_t port_id, uint8_t to_on); }; /** -- 2.20.1