Skip to content

Commit

Permalink
dpip: add 'maddr' subcommand to show multicast addresses
Browse files Browse the repository at this point in the history
Signed-off-by: ywc689 <[email protected]>
  • Loading branch information
ywc689 committed Jul 10, 2024
1 parent 2849ec1 commit e3562e6
Show file tree
Hide file tree
Showing 13 changed files with 380 additions and 58 deletions.
13 changes: 13 additions & 0 deletions include/conf/inetaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,17 @@ struct inet_addr_front {
};
#endif /* CONFIG_DPVS_AGENT */

struct inet_maddr_entry {
char ifname[IFNAMSIZ];
union inet_addr maddr;
int af;
uint32_t flags;
uint32_t refcnt;
} __attribute__((__packed__));

struct inet_maddr_array {
int nmaddr;
struct inet_maddr_entry maddrs[0];
} __attribute__((__packed__));

#endif /* __DPVS_INETADDR_CONF_H__ */
37 changes: 37 additions & 0 deletions include/conf/netif_addr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* DPVS is a software load balancer (Virtual Server) based on DPDK.
*
* Copyright (C) 2021 iQIYI (www.iqiyi.com).
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __DPVS_NETIF_ADDR_CONF_H__
#define __DPVS_NETIF_ADDR_CONF_H__

enum {
HW_ADDR_F_FROM_KNI = 1, // from linux kni device in local layer
};

struct netif_hw_addr_entry {
char addr[18];
uint32_t refcnt;
uint16_t flags;
uint16_t sync_cnt;
} __attribute__((__packed__));

struct netif_hw_addr_array {
int count;
struct netif_hw_addr_entry entries[0];
} __attribute__((__packed__));

#endif
2 changes: 2 additions & 0 deletions include/conf/sockopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
DPVSMSG(SOCKOPT_SET_IFADDR_SET) \
DPVSMSG(SOCKOPT_SET_IFADDR_FLUSH) \
DPVSMSG(SOCKOPT_GET_IFADDR_SHOW) \
DPVSMSG(SOCKOPT_GET_IFMADDR_SHOW) \
\
DPVSMSG(SOCKOPT_NETIF_SET_LCORE) \
DPVSMSG(SOCKOPT_NETIF_SET_PORT) \
Expand All @@ -98,6 +99,7 @@
DPVSMSG(SOCKOPT_NETIF_GET_PORT_XSTATS) \
DPVSMSG(SOCKOPT_NETIF_GET_PORT_EXT_INFO) \
DPVSMSG(SOCKOPT_NETIF_GET_BOND_STATUS) \
DPVSMSG(SOCKOPT_NETIF_GET_MADDR)\
DPVSMSG(SOCKOPT_NETIF_GET_MAX) \
\
DPVSMSG(SOCKOPT_SET_NEIGH_ADD) \
Expand Down
2 changes: 2 additions & 0 deletions include/inetaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ struct inet_device {
struct list_head ifa_list[DPVS_MAX_LCORE]; /* inet_ifaddr list */
struct list_head ifm_list[DPVS_MAX_LCORE]; /* inet_ifmcaddr list*/
uint32_t ifa_cnt[DPVS_MAX_LCORE];
uint32_t ifm_cnt[DPVS_MAX_LCORE];
rte_atomic32_t refcnt; /* not used yet */
#define this_ifa_list ifa_list[rte_lcore_id()]
#define this_ifm_list ifm_list[rte_lcore_id()]
#define this_ifa_cnt ifa_cnt[rte_lcore_id()]
#define this_ifm_cnt ifm_cnt[rte_lcore_id()]
};

/*
Expand Down
7 changes: 4 additions & 3 deletions include/netif_addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@
#ifndef __DPVS_NETIF_ADDR_H__
#define __DPVS_NETIF_ADDR_H__

enum {
HW_ADDR_F_FROM_KNI = 1, // from linux kni device in local layer
};
#include "conf/netif_addr.h"

struct netif_hw_addr {
struct list_head list;
Expand Down Expand Up @@ -55,6 +53,7 @@ int netif_mc_add(struct netif_port *dev, const struct rte_ether_addr *addr);
int netif_mc_del(struct netif_port *dev, const struct rte_ether_addr *addr);
void netif_mc_flush(struct netif_port *dev);
void netif_mc_init(struct netif_port *dev);

int __netif_mc_dump(struct netif_port *dev, uint16_t filter_flags,
struct rte_ether_addr *addrs, size_t *naddr);
int netif_mc_dump(struct netif_port *dev, uint16_t filter_flags,
Expand All @@ -74,6 +73,8 @@ int netif_mc_sync_multiple(struct netif_port *to, struct netif_port *from, int s
int __netif_mc_unsync_multiple(struct netif_port *to, struct netif_port *from, int sync_cnt);
int netif_mc_unsync_multiple(struct netif_port *to, struct netif_port *from, int sync_cnt);

int netif_get_multicast_addrs(struct netif_port *dev, void **out, size_t *outlen);

static inline int eth_addr_equal(const struct rte_ether_addr *addr1,
const struct rte_ether_addr *addr2)
{
Expand Down
139 changes: 103 additions & 36 deletions src/inetaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ static inline void imc_hash(struct inet_ifmcaddr *imc, struct inet_device *idev)
{
list_add(&imc->d_list, &idev->this_ifm_list);
++imc->refcnt;
++idev->this_ifm_cnt;
}

static inline void imc_unhash(struct inet_ifmcaddr *imc)
Expand All @@ -99,6 +100,7 @@ static inline void imc_unhash(struct inet_ifmcaddr *imc)

list_del(&imc->d_list);
--imc->refcnt;
--imc->idev->this_ifm_cnt;
}

static struct inet_ifmcaddr *imc_lookup(int af, const struct inet_device *idev,
Expand Down Expand Up @@ -1833,6 +1835,39 @@ static int ifaddr_get_verbose(struct inet_device *idev, struct inet_addr_data_ar
return err;
}

static int ifmaddr_fill_entries(struct inet_device *idev, struct inet_maddr_array **parray, int *plen)
{
lcoreid_t cid;
int ifm_cnt, len, off;
struct inet_ifmcaddr *ifm;
struct inet_maddr_array *array;

cid = rte_lcore_id();
ifm_cnt = idev->ifm_cnt[cid];

len = sizeof(struct inet_maddr_array) + ifm_cnt * sizeof(struct inet_maddr_entry);
array = rte_calloc(NULL, 1, len, RTE_CACHE_LINE_SIZE);
if (unlikely(!array))
return EDPVS_NOMEM;

off = 0;
list_for_each_entry(ifm, &idev->ifm_list[cid], d_list) {
strncpy(array->maddrs[off].ifname, ifm->idev->dev->name,
sizeof(array->maddrs[off].ifname) - 1);
array->maddrs[off].maddr = ifm->addr;
array->maddrs[off].af = ifm->af;
array->maddrs[off].flags = ifm->flags;
array->maddrs[off].refcnt = ifm->refcnt;
if (++off >= ifm_cnt)
break;
}
array->nmaddr = off;

*parray = array;
*plen = len;
return EDPVS_OK;
}

static int ifa_sockopt_set(sockoptid_t opt, const void *conf, size_t size)
{
struct netif_port *dev;
Expand Down Expand Up @@ -1967,60 +2002,92 @@ static int ifa_sockopt_get(sockoptid_t opt, const void *conf, size_t size,
int err, len = 0;
struct netif_port *dev;
struct inet_device *idev = NULL;

struct inet_addr_data_array *array = NULL;
const struct inet_addr_param *param = conf;

if (!conf || size < sizeof(struct inet_addr_param) || !out || !outsize)
struct inet_maddr_array *marray = NULL;
const char *ifname = conf;

if (!conf || !out || !outsize)
return EDPVS_INVAL;

if (opt != SOCKOPT_GET_IFADDR_SHOW)
return EDPVS_NOTSUPP;
switch (opt) {
case SOCKOPT_GET_IFADDR_SHOW:
if (size < sizeof(struct inet_addr_param) || param->ifa_ops != INET_ADDR_GET)
return EDPVS_INVAL;

if (param->ifa_ops != INET_ADDR_GET)
return EDPVS_INVAL;
if (param->ifa_entry.af != AF_INET &&
param->ifa_entry.af != AF_INET6 &&
param->ifa_entry.af != AF_UNSPEC)
return EDPVS_NOTSUPP;

if (param->ifa_entry.af != AF_INET &&
param->ifa_entry.af != AF_INET6 &&
param->ifa_entry.af != AF_UNSPEC)
return EDPVS_NOTSUPP;
if (strlen(param->ifa_entry.ifname)) {
dev = netif_port_get_by_name(param->ifa_entry.ifname);
if (!dev) {
RTE_LOG(WARNING, IFA, "%s: no such device: %s\n",
__func__, param->ifa_entry.ifname);
return EDPVS_NOTEXIST;
}
idev = dev_get_idev(dev);
if (!idev)
return EDPVS_RESOURCE;
}

if (param->ifa_ops_flags & IFA_F_OPS_VERBOSE)
err = ifaddr_get_verbose(idev, &array, &len);
else if (param->ifa_ops_flags & IFA_F_OPS_STATS)
err = ifaddr_get_stats(idev, &array, &len);
else
err = ifaddr_get_basic(idev, &array, &len);

if (strlen(param->ifa_entry.ifname)) {
dev = netif_port_get_by_name(param->ifa_entry.ifname);
if (err != EDPVS_OK) {
RTE_LOG(WARNING, IFA, "%s: fail to get inet addresses -- %s!\n",
__func__, dpvs_strerror(err));
return err;
}

if (idev)
idev_put(idev);

if (array) {
array->ops = INET_ADDR_GET;
array->ops_flags = param->ifa_ops_flags;
}

*out = array;
*outsize = len;
break;
case SOCKOPT_GET_IFMADDR_SHOW:
if (!size || strlen(ifname) == 0)
return EDPVS_INVAL;

dev = netif_port_get_by_name(ifname);
if (!dev) {
RTE_LOG(WARNING, IFA, "%s: no such device: %s\n",
__func__, param->ifa_entry.ifname);
RTE_LOG(WARNING, IFA, "%s: no such device: %s\n", __func__, ifname);
return EDPVS_NOTEXIST;
}

idev = dev_get_idev(dev);
if (!idev)
return EDPVS_RESOURCE;
}

if (param->ifa_ops_flags & IFA_F_OPS_VERBOSE)
err = ifaddr_get_verbose(idev, &array, &len);
else if (param->ifa_ops_flags & IFA_F_OPS_STATS)
err = ifaddr_get_stats(idev, &array, &len);
else
err = ifaddr_get_basic(idev, &array, &len);

if (err != EDPVS_OK) {
RTE_LOG(WARNING, IFA, "%s: fail to get inet addresses -- %s!\n",
__func__, dpvs_strerror(err));
return err;
}
err = ifmaddr_fill_entries(idev, &marray, &len);
if (err != EDPVS_OK) {
RTE_LOG(WARNING, IFA, "%s: fail to get inet maddresses -- %s!\n",
__func__, dpvs_strerror(err));
return err;
}

if (idev)
idev_put(idev);

if (array) {
array->ops = INET_ADDR_GET;
array->ops_flags = param->ifa_ops_flags;
*out = marray;
*outsize = len;
break;
default:
*out = NULL;
*outsize = 0;
return EDPVS_NOTSUPP;
}

*out = array;
*outsize = len;

return EDPVS_OK;
}

Expand Down Expand Up @@ -2067,7 +2134,7 @@ static struct dpvs_sockopts ifa_sockopts = {
.set_opt_max = SOCKOPT_SET_IFADDR_FLUSH,
.set = ifa_sockopt_set,
.get_opt_min = SOCKOPT_GET_IFADDR_SHOW,
.get_opt_max = SOCKOPT_GET_IFADDR_SHOW,
.get_opt_max = SOCKOPT_GET_IFMADDR_SHOW,
.get = ifa_sockopt_get,
};

Expand Down
2 changes: 1 addition & 1 deletion src/kni.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "conf/common.h"
#include "dpdk.h"
#include "netif.h"
#include "netif_addr.h"
#include "conf/netif_addr.h"
#include "ctrl.h"
#include "kni.h"
#include "vlan.h"
Expand Down
10 changes: 10 additions & 0 deletions src/netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "conf/common.h"
#include "netif.h"
#include "netif_addr.h"
#include "conf/netif_addr.h"
#include "vlan.h"
#include "ctrl.h"
#include "list.h"
Expand Down Expand Up @@ -5180,6 +5181,15 @@ static int netif_sockopt_get(sockoptid_t opt, const void *in, size_t inlen,
return EDPVS_NOTEXIST;
ret = get_bond_status(port, out, outlen);
break;
case SOCKOPT_NETIF_GET_MADDR:
if (!in)
return EDPVS_INVAL;
name = (char *)in;
port = netif_port_get_by_name(name);
if (!port)
return EDPVS_NOTEXIST;
ret = netif_get_multicast_addrs(port, out, outlen);
break;
default:
RTE_LOG(WARNING, NETIF,
"[%s] invalid netif get cmd: %d\n", __func__, opt);
Expand Down
Loading

0 comments on commit e3562e6

Please sign in to comment.