* [PATCH net-next 3/6] nfp: move the start/stop app callbacks back
From: Jakub Kicinski @ 2017-09-03 1:26 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170903012605.7435-1-jakub.kicinski@netronome.com>
Since representors are now created with a separate callback
start/stop app callbacks can be moved again to their original
location. They are intended to app-specific init/clean up
over the control channel.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 26 ++++++++++-------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index f2a1a4e2ce8b..5abb9ba31e7d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -469,10 +469,14 @@ static int nfp_net_pf_app_start(struct nfp_pf *pf)
{
int err;
- err = nfp_app_start(pf->app, pf->ctrl_vnic);
+ err = nfp_net_pf_app_start_ctrl(pf);
if (err)
return err;
+ err = nfp_app_start(pf->app, pf->ctrl_vnic);
+ if (err)
+ goto err_ctrl_stop;
+
if (pf->num_vfs) {
err = nfp_app_sriov_enable(pf->app, pf->num_vfs);
if (err)
@@ -483,6 +487,8 @@ static int nfp_net_pf_app_start(struct nfp_pf *pf)
err_app_stop:
nfp_app_stop(pf->app);
+err_ctrl_stop:
+ nfp_net_pf_app_stop_ctrl(pf);
return err;
}
@@ -491,6 +497,7 @@ static void nfp_net_pf_app_stop(struct nfp_pf *pf)
if (pf->num_vfs)
nfp_app_sriov_disable(pf->app);
nfp_app_stop(pf->app);
+ nfp_net_pf_app_stop_ctrl(pf);
}
static void nfp_net_pci_unmap_mem(struct nfp_pf *pf)
@@ -582,7 +589,7 @@ static int nfp_net_pci_map_mem(struct nfp_pf *pf)
static void nfp_net_pci_remove_finish(struct nfp_pf *pf)
{
- nfp_net_pf_app_stop_ctrl(pf);
+ nfp_net_pf_app_stop(pf);
/* stop app first, to avoid double free of ctrl vNIC's ddir */
nfp_net_debugfs_dir_clean(&pf->ddir);
@@ -713,7 +720,6 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
{
struct nfp_net_fw_version fw_ver;
u8 __iomem *ctrl_bar, *qc_bar;
- struct nfp_net *nn;
int stride;
int err;
@@ -790,7 +796,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err)
goto err_free_vnics;
- err = nfp_net_pf_app_start_ctrl(pf);
+ err = nfp_net_pf_app_start(pf);
if (err)
goto err_free_irqs;
@@ -798,20 +804,12 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err)
goto err_stop_app;
- err = nfp_net_pf_app_start(pf);
- if (err)
- goto err_clean_vnics;
-
mutex_unlock(&pf->lock);
return 0;
-err_clean_vnics:
- list_for_each_entry(nn, &pf->vnics, vnic_list)
- if (nfp_net_is_data_vnic(nn))
- nfp_net_pf_clean_vnic(pf, nn);
err_stop_app:
- nfp_net_pf_app_stop_ctrl(pf);
+ nfp_net_pf_app_stop(pf);
err_free_irqs:
nfp_net_pf_free_irqs(pf);
err_free_vnics:
@@ -835,8 +833,6 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
if (list_empty(&pf->vnics))
goto out;
- nfp_net_pf_app_stop(pf);
-
list_for_each_entry(nn, &pf->vnics, vnic_list)
if (nfp_net_is_data_vnic(nn))
nfp_net_pf_clean_vnic(pf, nn);
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 2/6] nfp: flower: base lifetime of representors on existence of lower vNIC
From: Jakub Kicinski @ 2017-09-03 1:26 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170903012605.7435-1-jakub.kicinski@netronome.com>
Create representors after lower vNIC is registered and destroy
them before it is destroyed. Move the code out of start/stop
callbacks directly into vnic_init/clean callbacks. Make sure
SR-IOV callbacks don't try to create representors when lower
device does not exist.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/flower/main.c | 66 +++++++++++++++---------
1 file changed, 43 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c
index db59858c0f19..91fe03617106 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -127,6 +127,11 @@ nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
static void nfp_flower_sriov_disable(struct nfp_app *app)
{
+ struct nfp_flower_priv *priv = app->priv;
+
+ if (!priv->nn)
+ return;
+
nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
}
@@ -203,18 +208,16 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
static int nfp_flower_sriov_enable(struct nfp_app *app, int num_vfs)
{
+ struct nfp_flower_priv *priv = app->priv;
+
+ if (!priv->nn)
+ return 0;
+
return nfp_flower_spawn_vnic_reprs(app,
NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
NFP_REPR_TYPE_VF, num_vfs);
}
-static void nfp_flower_stop(struct nfp_app *app)
-{
- nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
- nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
-
-}
-
static int
nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
{
@@ -300,19 +303,6 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
return err;
}
-static int nfp_flower_start(struct nfp_app *app)
-{
- int err;
-
- err = nfp_flower_spawn_phy_reprs(app, app->priv);
- if (err)
- return err;
-
- return nfp_flower_spawn_vnic_reprs(app,
- NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
- NFP_REPR_TYPE_PF, 1);
-}
-
static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
unsigned int id)
{
@@ -335,16 +325,49 @@ static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
{
struct nfp_flower_priv *priv = app->priv;
+ if (app->pf->num_vfs)
+ nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
+ nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
+ nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
+
priv->nn = NULL;
}
static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
{
struct nfp_flower_priv *priv = app->priv;
+ int err;
priv->nn = nn;
+ err = nfp_flower_spawn_phy_reprs(app, app->priv);
+ if (err)
+ goto err_clear_nn;
+
+ err = nfp_flower_spawn_vnic_reprs(app,
+ NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
+ NFP_REPR_TYPE_PF, 1);
+ if (err)
+ goto err_destroy_reprs_phy;
+
+ if (app->pf->num_vfs) {
+ err = nfp_flower_spawn_vnic_reprs(app,
+ NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
+ NFP_REPR_TYPE_VF,
+ app->pf->num_vfs);
+ if (err)
+ goto err_destroy_reprs_pf;
+ }
+
return 0;
+
+err_destroy_reprs_pf:
+ nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
+err_destroy_reprs_phy:
+ nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
+err_clear_nn:
+ priv->nn = NULL;
+ return err;
}
static int nfp_flower_init(struct nfp_app *app)
@@ -430,9 +453,6 @@ const struct nfp_app_type app_flower = {
.repr_open = nfp_flower_repr_netdev_open,
.repr_stop = nfp_flower_repr_netdev_stop,
- .start = nfp_flower_start,
- .stop = nfp_flower_stop,
-
.ctrl_msg_rx = nfp_flower_cmsg_rx,
.sriov_enable = nfp_flower_sriov_enable,
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 1/6] nfp: separate app vNIC init/clean from alloc/free
From: Jakub Kicinski @ 2017-09-03 1:26 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170903012605.7435-1-jakub.kicinski@netronome.com>
We currently only have one app callback for vNIC creation
and destruction. This is insufficient, because some actions
have to be taken before netdev is registered, after it's
registered and after it's unregistered. Old callbacks
were really corresponding to alloc/free actions. Rename
them and add proper init/clean. Apps using representors
will be able to use new callbacks to manage lifetime of
upper devices.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/bpf/main.c | 10 +++----
drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 2 +-
drivers/net/ethernet/netronome/nfp/flower/main.c | 27 +++++++++++++----
drivers/net/ethernet/netronome/nfp/flower/main.h | 2 ++
drivers/net/ethernet/netronome/nfp/nfp_app.c | 2 +-
drivers/net/ethernet/netronome/nfp/nfp_app.h | 35 +++++++++++++++++------
drivers/net/ethernet/netronome/nfp/nfp_app_nic.c | 4 +--
drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 16 +++++++++--
drivers/net/ethernet/netronome/nfp/nic/main.c | 2 +-
9 files changed, 73 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index f4de3a7377b0..be2cf10a2cd7 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -84,7 +84,7 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn)
}
static int
-nfp_bpf_vnic_init(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
+nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
{
struct nfp_net_bpf_priv *priv;
int ret;
@@ -106,14 +106,14 @@ nfp_bpf_vnic_init(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
setup_timer(&priv->rx_filter_stats_timer,
nfp_net_filter_stats_timer, (unsigned long)nn);
- ret = nfp_app_nic_vnic_init(app, nn, id);
+ ret = nfp_app_nic_vnic_alloc(app, nn, id);
if (ret)
kfree(priv);
return ret;
}
-static void nfp_bpf_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
+static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn)
{
if (nn->dp.bpf_offload_xdp)
nfp_bpf_xdp_offload(app, nn, NULL);
@@ -149,8 +149,8 @@ const struct nfp_app_type app_bpf = {
.extra_cap = nfp_bpf_extra_cap,
- .vnic_init = nfp_bpf_vnic_init,
- .vnic_clean = nfp_bpf_vnic_clean,
+ .vnic_alloc = nfp_bpf_vnic_alloc,
+ .vnic_free = nfp_bpf_vnic_free,
.setup_tc = nfp_bpf_setup_tc,
.tc_busy = nfp_bpf_tc_busy,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
index 806924b82adc..d82d9888d676 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
@@ -203,7 +203,7 @@ void nfp_flower_cmsg_process_rx(struct work_struct *work)
priv = container_of(work, struct nfp_flower_priv, cmsg_work);
while ((skb = skb_dequeue(&priv->cmsg_skbs)))
- nfp_flower_cmsg_process_one_rx(priv->nn->app, skb);
+ nfp_flower_cmsg_process_one_rx(priv->app, skb);
}
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c
index 126a6b5233bf..db59858c0f19 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -313,18 +313,14 @@ static int nfp_flower_start(struct nfp_app *app)
NFP_REPR_TYPE_PF, 1);
}
-static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn,
- unsigned int id)
+static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+ unsigned int id)
{
- struct nfp_flower_priv *priv = app->priv;
-
if (id > 0) {
nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
goto err_invalid_port;
}
- priv->nn = nn;
-
eth_hw_addr_random(nn->dp.netdev);
netif_keep_dst(nn->dp.netdev);
@@ -335,6 +331,22 @@ static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn,
return PTR_ERR_OR_ZERO(nn->port);
}
+static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
+{
+ struct nfp_flower_priv *priv = app->priv;
+
+ priv->nn = NULL;
+}
+
+static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
+{
+ struct nfp_flower_priv *priv = app->priv;
+
+ priv->nn = nn;
+
+ return 0;
+}
+
static int nfp_flower_init(struct nfp_app *app)
{
const struct nfp_pf *pf = app->pf;
@@ -374,6 +386,7 @@ static int nfp_flower_init(struct nfp_app *app)
return -ENOMEM;
app->priv = app_priv;
+ app_priv->app = app;
skb_queue_head_init(&app_priv->cmsg_skbs);
INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
@@ -410,7 +423,9 @@ const struct nfp_app_type app_flower = {
.init = nfp_flower_init,
.clean = nfp_flower_clean,
+ .vnic_alloc = nfp_flower_vnic_alloc,
.vnic_init = nfp_flower_vnic_init,
+ .vnic_clean = nfp_flower_vnic_clean,
.repr_open = nfp_flower_repr_netdev_open,
.repr_stop = nfp_flower_repr_netdev_stop,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h
index b7043ca9b9fc..c20dd00a1cae 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -72,6 +72,7 @@ struct nfp_fl_stats_id {
/**
* struct nfp_flower_priv - Flower APP per-vNIC priv data
+ * @app: Back pointer to app
* @nn: Pointer to vNIC
* @mask_id_seed: Seed used for mask hash table
* @flower_version: HW version of flower
@@ -83,6 +84,7 @@ struct nfp_fl_stats_id {
* @cmsg_skbs: List of skbs for control message processing
*/
struct nfp_flower_priv {
+ struct nfp_app *app;
struct nfp_net *nn;
u32 mask_id_seed;
u64 flower_version;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.c b/drivers/net/ethernet/netronome/nfp/nfp_app.c
index 505e63f47419..82c290763529 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.c
@@ -125,7 +125,7 @@ struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id)
return ERR_PTR(-EINVAL);
}
- if (WARN_ON(!apps[i]->name || !apps[i]->vnic_init))
+ if (WARN_ON(!apps[i]->name || !apps[i]->vnic_alloc))
return ERR_PTR(-EINVAL);
app = kzalloc(sizeof(*app), GFP_KERNEL);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h
index c13b9bbe7e62..af640b5c2108 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h
@@ -69,8 +69,10 @@ extern const struct nfp_app_type app_flower;
* @init: perform basic app checks and init
* @clean: clean app state
* @extra_cap: extra capabilities string
- * @vnic_init: init vNICs (assign port types, etc.)
- * @vnic_clean: clean up app's vNIC state
+ * @vnic_alloc: allocate vNICs (assign port types, etc.)
+ * @vnic_free: free up app's vNIC state
+ * @vnic_init: vNIC netdev was registered
+ * @vnic_clean: vNIC netdev about to be unregistered
* @repr_open: representor netdev open callback
* @repr_stop: representor netdev stop callback
* @start: start application logic
@@ -95,8 +97,10 @@ struct nfp_app_type {
const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
- int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn,
- unsigned int id);
+ int (*vnic_alloc)(struct nfp_app *app, struct nfp_net *nn,
+ unsigned int id);
+ void (*vnic_free)(struct nfp_app *app, struct nfp_net *nn);
+ int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn);
void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
@@ -157,10 +161,23 @@ static inline void nfp_app_clean(struct nfp_app *app)
app->type->clean(app);
}
-static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn,
- unsigned int id)
+static inline int nfp_app_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+ unsigned int id)
{
- return app->type->vnic_init(app, nn, id);
+ return app->type->vnic_alloc(app, nn, id);
+}
+
+static inline void nfp_app_vnic_free(struct nfp_app *app, struct nfp_net *nn)
+{
+ if (app->type->vnic_free)
+ app->type->vnic_free(app, nn);
+}
+
+static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn)
+{
+ if (!app->type->vnic_init)
+ return 0;
+ return app->type->vnic_init(app, nn);
}
static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
@@ -308,7 +325,7 @@ void nfp_app_free(struct nfp_app *app);
/* Callbacks shared between apps */
-int nfp_app_nic_vnic_init(struct nfp_app *app, struct nfp_net *nn,
- unsigned int id);
+int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+ unsigned int id);
#endif
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c
index 4e37c81f9eaf..2a2f2fbc8850 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c
@@ -60,8 +60,8 @@ nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
return nn->port->type == NFP_PORT_INVALID;
}
-int nfp_app_nic_vnic_init(struct nfp_app *app, struct nfp_net *nn,
- unsigned int id)
+int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+ unsigned int id)
{
int err;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 7c22cc4654b7..f2a1a4e2ce8b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -161,6 +161,8 @@ nfp_net_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt,
static void nfp_net_pf_free_vnic(struct nfp_pf *pf, struct nfp_net *nn)
{
+ if (nfp_net_is_data_vnic(nn))
+ nfp_app_vnic_free(pf->app, nn);
nfp_port_free(nn->port);
list_del(&nn->vnic_list);
pf->num_vnics--;
@@ -205,7 +207,7 @@ nfp_net_pf_alloc_vnic(struct nfp_pf *pf, bool needs_netdev,
nn->stride_tx = stride;
if (needs_netdev) {
- err = nfp_app_vnic_init(pf->app, nn, id);
+ err = nfp_app_vnic_alloc(pf->app, nn, id);
if (err) {
nfp_net_free(nn);
return ERR_PTR(err);
@@ -243,8 +245,17 @@ nfp_net_pf_init_vnic(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id)
nfp_net_info(nn);
+ if (nfp_net_is_data_vnic(nn)) {
+ err = nfp_app_vnic_init(pf->app, nn);
+ if (err)
+ goto err_devlink_port_clean;
+ }
+
return 0;
+err_devlink_port_clean:
+ if (nn->port)
+ nfp_devlink_port_unregister(nn->port);
err_dfs_clean:
nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
nfp_net_clean(nn);
@@ -288,11 +299,12 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar,
static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn)
{
+ if (nfp_net_is_data_vnic(nn))
+ nfp_app_vnic_clean(pf->app, nn);
if (nn->port)
nfp_devlink_port_unregister(nn->port);
nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
nfp_net_clean(nn);
- nfp_app_vnic_clean(pf->app, nn);
}
static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf)
diff --git a/drivers/net/ethernet/netronome/nfp/nic/main.c b/drivers/net/ethernet/netronome/nfp/nic/main.c
index 8287a85d22c1..d5b587fccaa3 100644
--- a/drivers/net/ethernet/netronome/nfp/nic/main.c
+++ b/drivers/net/ethernet/netronome/nfp/nic/main.c
@@ -63,7 +63,7 @@ const struct nfp_app_type app_nic = {
.name = "nic",
.init = nfp_nic_init,
- .vnic_init = nfp_app_nic_vnic_init,
+ .vnic_alloc = nfp_app_nic_vnic_alloc,
.sriov_enable = nfp_nic_sriov_enable,
.sriov_disable = nfp_nic_sriov_disable,
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 0/6] nfp: refactor app init, and minor flower fixes
From: Jakub Kicinski @ 2017-09-03 1:25 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
Hi!
This series is a part 2 to what went into net as a simpler fix.
In net we simply moved when existing callbacks are invoked to
ensure flower app does not still use representors when lower
netdev has already been destroyed. In this series we add a
callback to notify apps when vNIC netdevs are fully initialized
and they are about to be destroyed. This allows flower to spawn
representors at the right time, while keeping the start/stop
callbacks for what they are intended to be used - FW initialization
over control channel.
Patch 4 improves drop monitor interaction and patch 5 changes
the default Kconfig selection of flower offload. Patch 6 fixes
locking around representor updates which got lost in net-next.
Jakub Kicinski (6):
nfp: separate app vNIC init/clean from alloc/free
nfp: flower: base lifetime of representors on existence of lower vNIC
nfp: move the start/stop app callbacks back
nfp: be drop monitor friendly
nfp: build the flower offload by default
nfp: flower: restore RTNL locking around representor updates
drivers/net/ethernet/netronome/Kconfig | 1 +
drivers/net/ethernet/netronome/nfp/bpf/main.c | 10 +--
drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 11 ++-
drivers/net/ethernet/netronome/nfp/flower/main.c | 93 +++++++++++++++-------
drivers/net/ethernet/netronome/nfp/flower/main.h | 2 +
drivers/net/ethernet/netronome/nfp/nfp_app.c | 2 +-
drivers/net/ethernet/netronome/nfp/nfp_app.h | 35 +++++---
drivers/net/ethernet/netronome/nfp/nfp_app_nic.c | 4 +-
.../net/ethernet/netronome/nfp/nfp_net_common.c | 2 +-
drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 42 ++++++----
drivers/net/ethernet/netronome/nfp/nic/main.c | 2 +-
11 files changed, 136 insertions(+), 68 deletions(-)
--
2.14.1
^ permalink raw reply
* [net-next:master 428/478] include/linux/soc/ti/knav_dma.h:129:30: error: field 'direction' has incomplete type
From: kbuild test robot @ 2017-09-03 0:23 UTC (permalink / raw)
To: Dave Jiang; +Cc: kbuild-all, netdev
[-- Attachment #1: Type: text/plain, Size: 4312 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git master
head: 32d9b70a053a835b4dfb33158fc03795ea103e44
commit: 0dd5759dbb1c9a862e7d90c09d6cf398c45f1100 [428/478] net: remove dmaengine.h inclusion from netdevice.h
config: arm-keystone_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 0dd5759dbb1c9a862e7d90c09d6cf398c45f1100
# save the attached .config to linux build tree
make.cross ARCH=arm
All errors (new ones prefixed by >>):
In file included from drivers/net/ethernet/ti/netcp_core.c:30:0:
>> include/linux/soc/ti/knav_dma.h:129:30: error: field 'direction' has incomplete type
enum dma_transfer_direction direction;
^~~~~~~~~
drivers/net/ethernet/ti/netcp_core.c: In function 'netcp_txpipe_open':
drivers/net/ethernet/ti/netcp_core.c:1349:21: error: 'DMA_MEM_TO_DEV' undeclared (first use in this function)
config.direction = DMA_MEM_TO_DEV;
^~~~~~~~~~~~~~
drivers/net/ethernet/ti/netcp_core.c:1349:21: note: each undeclared identifier is reported only once for each function it appears in
drivers/net/ethernet/ti/netcp_core.c: In function 'netcp_setup_navigator_resources':
>> drivers/net/ethernet/ti/netcp_core.c:1659:22: error: 'DMA_DEV_TO_MEM' undeclared (first use in this function)
config.direction = DMA_DEV_TO_MEM;
^~~~~~~~~~~~~~
--
In file included from drivers/net/ethernet/ti/netcp.h:25:0,
from drivers/net/ethernet/ti/netcp_ethss.c:31:
>> include/linux/soc/ti/knav_dma.h:129:30: error: field 'direction' has incomplete type
enum dma_transfer_direction direction;
^~~~~~~~~
--
In file included from drivers/net//ethernet/ti/netcp_core.c:30:0:
>> include/linux/soc/ti/knav_dma.h:129:30: error: field 'direction' has incomplete type
enum dma_transfer_direction direction;
^~~~~~~~~
drivers/net//ethernet/ti/netcp_core.c: In function 'netcp_txpipe_open':
drivers/net//ethernet/ti/netcp_core.c:1349:21: error: 'DMA_MEM_TO_DEV' undeclared (first use in this function)
config.direction = DMA_MEM_TO_DEV;
^~~~~~~~~~~~~~
drivers/net//ethernet/ti/netcp_core.c:1349:21: note: each undeclared identifier is reported only once for each function it appears in
drivers/net//ethernet/ti/netcp_core.c: In function 'netcp_setup_navigator_resources':
drivers/net//ethernet/ti/netcp_core.c:1659:22: error: 'DMA_DEV_TO_MEM' undeclared (first use in this function)
config.direction = DMA_DEV_TO_MEM;
^~~~~~~~~~~~~~
vim +/direction +129 include/linux/soc/ti/knav_dma.h
88139ed0 Santosh Shilimkar 2014-03-30 121
88139ed0 Santosh Shilimkar 2014-03-30 122 /**
88139ed0 Santosh Shilimkar 2014-03-30 123 * struct knav_dma_cfg: Pktdma channel configuration
88139ed0 Santosh Shilimkar 2014-03-30 124 * @sl_cfg: Slave configuration
88139ed0 Santosh Shilimkar 2014-03-30 125 * @tx: Tx channel configuration
88139ed0 Santosh Shilimkar 2014-03-30 126 * @rx: Rx flow configuration
88139ed0 Santosh Shilimkar 2014-03-30 127 */
88139ed0 Santosh Shilimkar 2014-03-30 128 struct knav_dma_cfg {
88139ed0 Santosh Shilimkar 2014-03-30 @129 enum dma_transfer_direction direction;
88139ed0 Santosh Shilimkar 2014-03-30 130 union {
88139ed0 Santosh Shilimkar 2014-03-30 131 struct knav_dma_tx_cfg tx;
88139ed0 Santosh Shilimkar 2014-03-30 132 struct knav_dma_rx_cfg rx;
88139ed0 Santosh Shilimkar 2014-03-30 133 } u;
88139ed0 Santosh Shilimkar 2014-03-30 134 };
88139ed0 Santosh Shilimkar 2014-03-30 135
:::::: The code at line 129 was first introduced by commit
:::::: 88139ed030583557751e279968e13e892ae10825 soc: ti: add Keystone Navigator DMA support
:::::: TO: Santosh Shilimkar <santosh.shilimkar@ti.com>
:::::: CC: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 20668 bytes --]
^ permalink raw reply
* Re: [PATCH] staging: r8822be: Fix typo for CONFIG_RTLWIFI_DEBUG
From: kbuild test robot @ 2017-09-03 0:18 UTC (permalink / raw)
To: Andreas Ziegler
Cc: kbuild-all, Ping-Ke Shih, Larry Finger, gregkh, Yan-Hsuan Chuang,
Birming Chiu, Shaofu, Steven Ting, netdev, devel
In-Reply-To: <0758af1e-f8d5-97be-8308-ba5535ab9415@fau.de>
[-- Attachment #1: Type: text/plain, Size: 5548 bytes --]
Hi Andreas,
[auto build test ERROR on staging/staging-testing]
[cannot apply to v4.13-rc7 next-20170901]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Andreas-Ziegler/staging-r8822be-Fix-typo-for-CONFIG_RTLWIFI_DEBUG/20170830-144151
config: sparc64-allmodconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=sparc64
All errors (new ones prefixed by >>):
drivers/staging//rtlwifi/halmac/rtl_halmac.c: In function 'deinit_priv':
>> drivers/staging//rtlwifi/halmac/rtl_halmac.c:395:22: error: 'struct rtl_halmac_indicator' has no member named 'sctx'
if (!indicator[i].sctx)
^
In file included from drivers/staging//rtlwifi/halmac/../wifi.h:38:0,
from drivers/staging//rtlwifi/halmac/halmac_2_platform.h:28,
from drivers/staging//rtlwifi/halmac/halmac_api.h:38,
from drivers/staging//rtlwifi/halmac/rtl_halmac.c:26:
drivers/staging//rtlwifi/halmac/rtl_halmac.c:399:6: error: 'rtlpriv' undeclared (first use in this function)
rtlpriv, COMP_HALMAC, DBG_LOUD,
^
drivers/staging//rtlwifi/halmac/../debug.h:185:17: note: in definition of macro 'RT_TRACE'
_rtl_dbg_trace(rtlpriv, comp, level, \
^~~~~~~
drivers/staging//rtlwifi/halmac/rtl_halmac.c:399:6: note: each undeclared identifier is reported only once for each function it appears in
rtlpriv, COMP_HALMAC, DBG_LOUD,
^
drivers/staging//rtlwifi/halmac/../debug.h:185:17: note: in definition of macro 'RT_TRACE'
_rtl_dbg_trace(rtlpriv, comp, level, \
^~~~~~~
drivers/staging//rtlwifi/halmac/rtl_halmac.c:403:24: error: 'struct rtl_halmac_indicator' has no member named 'sctx'
sctx = indicator[i].sctx;
^
drivers/staging//rtlwifi/halmac/rtl_halmac.c:404:17: error: 'struct rtl_halmac_indicator' has no member named 'sctx'
indicator[i].sctx = NULL;
^
drivers/staging//rtlwifi/halmac/rtl_halmac.c:405:5: error: implicit declaration of function 'rtl_mfree' [-Werror=implicit-function-declaration]
rtl_mfree((u8 *)sctx, sizeof(*sctx));
^~~~~~~~~
>> drivers/staging//rtlwifi/halmac/rtl_halmac.c:405:34: error: dereferencing pointer to incomplete type 'struct submit_ctx'
rtl_mfree((u8 *)sctx, sizeof(*sctx));
^~~~~
cc1: some warnings being treated as errors
vim +405 drivers/staging//rtlwifi/halmac/rtl_halmac.c
938a0447 Ping-Ke Shih 2017-08-17 378
938a0447 Ping-Ke Shih 2017-08-17 379 static void deinit_priv(struct rtl_halmac *halmac)
938a0447 Ping-Ke Shih 2017-08-17 380 {
938a0447 Ping-Ke Shih 2017-08-17 381 struct rtl_halmac_indicator *indicator;
938a0447 Ping-Ke Shih 2017-08-17 382
938a0447 Ping-Ke Shih 2017-08-17 383 indicator = halmac->indicator;
938a0447 Ping-Ke Shih 2017-08-17 384 halmac->indicator = NULL;
938a0447 Ping-Ke Shih 2017-08-17 385 if (indicator) {
938a0447 Ping-Ke Shih 2017-08-17 386 u32 count, size;
938a0447 Ping-Ke Shih 2017-08-17 387
938a0447 Ping-Ke Shih 2017-08-17 388 count = HALMAC_FEATURE_ALL + 1;
bb304b2b Andreas Ziegler 2017-08-29 389 #ifdef CONFIG_RTLWIFI_DEBUG
938a0447 Ping-Ke Shih 2017-08-17 390 {
938a0447 Ping-Ke Shih 2017-08-17 391 struct submit_ctx *sctx;
938a0447 Ping-Ke Shih 2017-08-17 392 u32 i;
938a0447 Ping-Ke Shih 2017-08-17 393
938a0447 Ping-Ke Shih 2017-08-17 394 for (i = 0; i < count; i++) {
938a0447 Ping-Ke Shih 2017-08-17 @395 if (!indicator[i].sctx)
938a0447 Ping-Ke Shih 2017-08-17 396 continue;
938a0447 Ping-Ke Shih 2017-08-17 397
938a0447 Ping-Ke Shih 2017-08-17 398 RT_TRACE(
938a0447 Ping-Ke Shih 2017-08-17 399 rtlpriv, COMP_HALMAC, DBG_LOUD,
938a0447 Ping-Ke Shih 2017-08-17 400 "%s: <WARN> %s id(%d) sctx still exist!!\n",
938a0447 Ping-Ke Shih 2017-08-17 401 __func__, RTL_HALMAC_FEATURE_NAME[i],
938a0447 Ping-Ke Shih 2017-08-17 402 i);
938a0447 Ping-Ke Shih 2017-08-17 @403 sctx = indicator[i].sctx;
938a0447 Ping-Ke Shih 2017-08-17 404 indicator[i].sctx = NULL;
938a0447 Ping-Ke Shih 2017-08-17 @405 rtl_mfree((u8 *)sctx, sizeof(*sctx));
938a0447 Ping-Ke Shih 2017-08-17 406 }
938a0447 Ping-Ke Shih 2017-08-17 407 }
bb304b2b Andreas Ziegler 2017-08-29 408 #endif /* !CONFIG_RTLWIFI_DEBUG */
938a0447 Ping-Ke Shih 2017-08-17 409 size = sizeof(*indicator) * count;
938a0447 Ping-Ke Shih 2017-08-17 410 kfree((u8 *)indicator);
938a0447 Ping-Ke Shih 2017-08-17 411 }
938a0447 Ping-Ke Shih 2017-08-17 412 }
938a0447 Ping-Ke Shih 2017-08-17 413
:::::: The code at line 405 was first introduced by commit
:::::: 938a0447f094233e269f7f5ded474b13f3de8d80 staging: r8822be: Add code for halmac sub-driver
:::::: TO: Ping-Ke Shih <pkshih@realtek.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 50741 bytes --]
^ permalink raw reply
* (unknown),
From: netgalley @ 2017-09-02 23:56 UTC (permalink / raw)
To: netdev
[-- Attachment #1: 111116.doc --]
[-- Type: application/msword, Size: 40147 bytes --]
^ permalink raw reply
* Re: [pull request][net-next 0/3] Mellanox, mlx5 GRE tunnel offloads
From: Saeed Mahameed @ 2017-09-02 23:01 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: Saeed Mahameed, David S. Miller, Linux Netdev List
In-Reply-To: <87fuc7ong0.fsf@stressinduktion.org>
On Thu, Aug 31, 2017 at 6:51 AM, Hannes Frederic Sowa
<hannes@stressinduktion.org> wrote:
> Saeed Mahameed <saeedm@mellanox.com> writes:
>
>> The first patch from Gal and Ariel provides the mlx5 driver support for
>> ConnectX capability to perform IP version identification and matching in
>> order to distinguish between IPv4 and IPv6 without the need to specify the
>> encapsulation type, thus perform RSS in MPLS automatically without
>> specifying MPLS ethertyoe. This patch will also serve for inner GRE IPv4/6
>> classification for inner GRE RSS.
>
> I don't think this is legal at all or did I misunderstood something?
>
> <https://tools.ietf.org/html/rfc3032#section-2.2>
It seems you misunderstood the cover letter. The HW will still
identify MPLS (IPv4/IPv6) packets using a new bit we specify in the HW
steering rules rather than adding new specific rules with {MPLS
ethertype} X {IPv4,IPv6} to classify MPLS IPv{4,6} traffic, Same
functionality a better and general way to approach it.
Bottom line the hardware is capable of processing MPLS headers and
perform RSS on the inner packet (IPv4/6) without the need of the
driver to provide precise steering MPLS rules.
>
> Thanks,
> Hannes
^ permalink raw reply
* Re: [PATCH net-next 2/2] net: convert (struct ubuf_info)->refcnt to refcount_t
From: kbuild test robot @ 2017-09-02 21:58 UTC (permalink / raw)
To: Eric Dumazet
Cc: kbuild-all, David S . Miller, netdev, Willem de Bruijn,
Eric Dumazet, Eric Dumazet
In-Reply-To: <20170831203013.9219-3-edumazet@google.com>
[-- Attachment #1: Type: text/plain, Size: 12764 bytes --]
Hi Eric,
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/net-ubuf_info-refcnt-conversion/20170903-043506
config: x86_64-acpi-redef (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers//vhost/net.c: In function 'handle_tx':
>> drivers//vhost/net.c:536:15: error: passing argument 1 of 'atomic_set' from incompatible pointer type [-Werror=incompatible-pointer-types]
atomic_set(&ubuf->refcnt, 1);
^
In file included from include/linux/atomic.h:4:0,
from include/linux/jump_label.h:183,
from arch/x86/include/asm/string_64.h:5,
from arch/x86/include/asm/string.h:4,
from include/linux/string.h:18,
from include/linux/bitmap.h:8,
from include/linux/cpumask.h:11,
from arch/x86/include/asm/cpumask.h:4,
from arch/x86/include/asm/msr.h:10,
from arch/x86/include/asm/processor.h:20,
from arch/x86/include/asm/cpufeature.h:4,
from arch/x86/include/asm/thread_info.h:52,
from include/linux/thread_info.h:37,
from arch/x86/include/asm/preempt.h:6,
from include/linux/preempt.h:80,
from include/linux/spinlock.h:50,
from include/linux/seqlock.h:35,
from include/linux/time.h:5,
from include/linux/stat.h:18,
from include/linux/compat.h:12,
from drivers//vhost/net.c:9:
arch/x86/include/asm/atomic.h:36:29: note: expected 'atomic_t * {aka struct <anonymous> *}' but argument is of type 'refcount_t * {aka struct refcount_struct *}'
static __always_inline void atomic_set(atomic_t *v, int i)
^~~~~~~~~~
cc1: some warnings being treated as errors
vim +/atomic_set +536 drivers//vhost/net.c
0ed005ce0 Jason Wang 2017-01-18 442
3a4d5c94e Michael S. Tsirkin 2010-01-14 443 /* Expects to be always run from workqueue - which acts as
3a4d5c94e Michael S. Tsirkin 2010-01-14 444 * read-size critical section for our kind of RCU. */
3a4d5c94e Michael S. Tsirkin 2010-01-14 445 static void handle_tx(struct vhost_net *net)
3a4d5c94e Michael S. Tsirkin 2010-01-14 446 {
2839400f8 Asias He 2013-04-27 447 struct vhost_net_virtqueue *nvq = &net->vqs[VHOST_NET_VQ_TX];
81f95a558 Michael S. Tsirkin 2013-04-28 448 struct vhost_virtqueue *vq = &nvq->vq;
98a527aac Al Viro 2014-12-10 449 unsigned out, in;
d5675bd20 Michael S. Tsirkin 2010-06-24 450 int head;
3a4d5c94e Michael S. Tsirkin 2010-01-14 451 struct msghdr msg = {
3a4d5c94e Michael S. Tsirkin 2010-01-14 452 .msg_name = NULL,
3a4d5c94e Michael S. Tsirkin 2010-01-14 453 .msg_namelen = 0,
3a4d5c94e Michael S. Tsirkin 2010-01-14 454 .msg_control = NULL,
3a4d5c94e Michael S. Tsirkin 2010-01-14 455 .msg_controllen = 0,
3a4d5c94e Michael S. Tsirkin 2010-01-14 456 .msg_flags = MSG_DONTWAIT,
3a4d5c94e Michael S. Tsirkin 2010-01-14 457 };
3a4d5c94e Michael S. Tsirkin 2010-01-14 458 size_t len, total_len = 0;
70181d512 Jason Wang 2013-04-10 459 int err;
3a4d5c94e Michael S. Tsirkin 2010-01-14 460 size_t hdr_size;
28457ee69 Arnd Bergmann 2010-03-09 461 struct socket *sock;
fe729a57c Asias He 2013-05-06 462 struct vhost_net_ubuf_ref *uninitialized_var(ubufs);
cedb9bdce Michael S. Tsirkin 2012-12-06 463 bool zcopy, zcopy_used;
28457ee69 Arnd Bergmann 2010-03-09 464
2e26af79b Asias He 2013-05-07 465 mutex_lock(&vq->mutex);
2e26af79b Asias He 2013-05-07 466 sock = vq->private_data;
3a4d5c94e Michael S. Tsirkin 2010-01-14 467 if (!sock)
2e26af79b Asias He 2013-05-07 468 goto out;
3a4d5c94e Michael S. Tsirkin 2010-01-14 469
6b1e6cc78 Jason Wang 2016-06-23 470 if (!vq_iotlb_prefetch(vq))
6b1e6cc78 Jason Wang 2016-06-23 471 goto out;
6b1e6cc78 Jason Wang 2016-06-23 472
8ea8cf89e Michael S. Tsirkin 2011-05-20 473 vhost_disable_notify(&net->dev, vq);
3a4d5c94e Michael S. Tsirkin 2010-01-14 474
81f95a558 Michael S. Tsirkin 2013-04-28 475 hdr_size = nvq->vhost_hlen;
2839400f8 Asias He 2013-04-27 476 zcopy = nvq->ubufs;
3a4d5c94e Michael S. Tsirkin 2010-01-14 477
3a4d5c94e Michael S. Tsirkin 2010-01-14 478 for (;;) {
bab632d69 Michael S. Tsirkin 2011-07-18 479 /* Release DMAs done buffers first */
bab632d69 Michael S. Tsirkin 2011-07-18 480 if (zcopy)
eaae8132e Michael S. Tsirkin 2012-11-01 481 vhost_zerocopy_signal_used(net, vq);
bab632d69 Michael S. Tsirkin 2011-07-18 482
f7c6be404 Jason Wang 2013-09-02 483 /* If more outstanding DMAs, queue the work.
f7c6be404 Jason Wang 2013-09-02 484 * Handle upend_idx wrap around
f7c6be404 Jason Wang 2013-09-02 485 */
0ed005ce0 Jason Wang 2017-01-18 486 if (unlikely(vhost_exceeds_maxpend(net)))
f7c6be404 Jason Wang 2013-09-02 487 break;
f7c6be404 Jason Wang 2013-09-02 488
030881372 Jason Wang 2016-03-04 489 head = vhost_net_tx_get_vq_desc(net, vq, vq->iov,
3a4d5c94e Michael S. Tsirkin 2010-01-14 490 ARRAY_SIZE(vq->iov),
030881372 Jason Wang 2016-03-04 491 &out, &in);
d5675bd20 Michael S. Tsirkin 2010-06-24 492 /* On error, stop handling until the next kick. */
7b3384fc3 Michael S. Tsirkin 2010-07-01 493 if (unlikely(head < 0))
d5675bd20 Michael S. Tsirkin 2010-06-24 494 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 495 /* Nothing new? Wait for eventfd to tell us they refilled. */
3a4d5c94e Michael S. Tsirkin 2010-01-14 496 if (head == vq->num) {
8ea8cf89e Michael S. Tsirkin 2011-05-20 497 if (unlikely(vhost_enable_notify(&net->dev, vq))) {
8ea8cf89e Michael S. Tsirkin 2011-05-20 498 vhost_disable_notify(&net->dev, vq);
3a4d5c94e Michael S. Tsirkin 2010-01-14 499 continue;
3a4d5c94e Michael S. Tsirkin 2010-01-14 500 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 501 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 502 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 503 if (in) {
3a4d5c94e Michael S. Tsirkin 2010-01-14 504 vq_err(vq, "Unexpected descriptor format for TX: "
3a4d5c94e Michael S. Tsirkin 2010-01-14 505 "out %d, int %d\n", out, in);
3a4d5c94e Michael S. Tsirkin 2010-01-14 506 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 507 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 508 /* Skip header. TODO: support TSO. */
3a4d5c94e Michael S. Tsirkin 2010-01-14 509 len = iov_length(vq->iov, out);
c0371da60 Al Viro 2014-11-24 510 iov_iter_init(&msg.msg_iter, WRITE, vq->iov, out, len);
98a527aac Al Viro 2014-12-10 511 iov_iter_advance(&msg.msg_iter, hdr_size);
3a4d5c94e Michael S. Tsirkin 2010-01-14 512 /* Sanity check */
01e97e651 Al Viro 2014-12-15 513 if (!msg_data_left(&msg)) {
3a4d5c94e Michael S. Tsirkin 2010-01-14 514 vq_err(vq, "Unexpected header len for TX: "
3a4d5c94e Michael S. Tsirkin 2010-01-14 515 "%zd expected %zd\n",
98a527aac Al Viro 2014-12-10 516 len, hdr_size);
3a4d5c94e Michael S. Tsirkin 2010-01-14 517 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 518 }
01e97e651 Al Viro 2014-12-15 519 len = msg_data_left(&msg);
ce21a0291 Jason Wang 2013-09-02 520
ce21a0291 Jason Wang 2013-09-02 521 zcopy_used = zcopy && len >= VHOST_GOODCOPY_LEN
ce21a0291 Jason Wang 2013-09-02 522 && (nvq->upend_idx + 1) % UIO_MAXIOV !=
ce21a0291 Jason Wang 2013-09-02 523 nvq->done_idx
ce21a0291 Jason Wang 2013-09-02 524 && vhost_net_tx_select_zcopy(net);
cedb9bdce Michael S. Tsirkin 2012-12-06 525
bab632d69 Michael S. Tsirkin 2011-07-18 526 /* use msg_control to pass vhost zerocopy ubuf info to skb */
cedb9bdce Michael S. Tsirkin 2012-12-06 527 if (zcopy_used) {
46aa92d1b Michael S. Tsirkin 2013-03-17 528 struct ubuf_info *ubuf;
2839400f8 Asias He 2013-04-27 529 ubuf = nvq->ubuf_info + nvq->upend_idx;
bab632d69 Michael S. Tsirkin 2011-07-18 530
8b38694a2 Michael S. Tsirkin 2014-10-24 531 vq->heads[nvq->upend_idx].id = cpu_to_vhost32(vq, head);
ce21a0291 Jason Wang 2013-09-02 532 vq->heads[nvq->upend_idx].len = VHOST_DMA_IN_PROGRESS;
bab632d69 Michael S. Tsirkin 2011-07-18 533 ubuf->callback = vhost_zerocopy_callback;
2839400f8 Asias He 2013-04-27 534 ubuf->ctx = nvq->ubufs;
2839400f8 Asias He 2013-04-27 535 ubuf->desc = nvq->upend_idx;
1f8b977ab Willem de Bruijn 2017-08-03 @536 atomic_set(&ubuf->refcnt, 1);
bab632d69 Michael S. Tsirkin 2011-07-18 537 msg.msg_control = ubuf;
bab632d69 Michael S. Tsirkin 2011-07-18 538 msg.msg_controllen = sizeof(ubuf);
2839400f8 Asias He 2013-04-27 539 ubufs = nvq->ubufs;
0ad8b480d Michael S. Tsirkin 2014-02-13 540 atomic_inc(&ubufs->refcount);
2839400f8 Asias He 2013-04-27 541 nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV;
ce21a0291 Jason Wang 2013-09-02 542 } else {
4364d5f96 Jason Wang 2013-06-05 543 msg.msg_control = NULL;
ce21a0291 Jason Wang 2013-09-02 544 ubufs = NULL;
ce21a0291 Jason Wang 2013-09-02 545 }
0ed005ce0 Jason Wang 2017-01-18 546
0ed005ce0 Jason Wang 2017-01-18 547 total_len += len;
0ed005ce0 Jason Wang 2017-01-18 548 if (total_len < VHOST_NET_WEIGHT &&
0ed005ce0 Jason Wang 2017-01-18 549 !vhost_vq_avail_empty(&net->dev, vq) &&
0ed005ce0 Jason Wang 2017-01-18 550 likely(!vhost_exceeds_maxpend(net))) {
0ed005ce0 Jason Wang 2017-01-18 551 msg.msg_flags |= MSG_MORE;
0ed005ce0 Jason Wang 2017-01-18 552 } else {
0ed005ce0 Jason Wang 2017-01-18 553 msg.msg_flags &= ~MSG_MORE;
0ed005ce0 Jason Wang 2017-01-18 554 }
0ed005ce0 Jason Wang 2017-01-18 555
3a4d5c94e Michael S. Tsirkin 2010-01-14 556 /* TODO: Check specific error and bomb out unless ENOBUFS? */
1b7841404 Ying Xue 2015-03-02 557 err = sock->ops->sendmsg(sock, &msg, len);
3a4d5c94e Michael S. Tsirkin 2010-01-14 558 if (unlikely(err < 0)) {
cedb9bdce Michael S. Tsirkin 2012-12-06 559 if (zcopy_used) {
fe729a57c Asias He 2013-05-06 560 vhost_net_ubuf_put(ubufs);
2839400f8 Asias He 2013-04-27 561 nvq->upend_idx = ((unsigned)nvq->upend_idx - 1)
2839400f8 Asias He 2013-04-27 562 % UIO_MAXIOV;
bab632d69 Michael S. Tsirkin 2011-07-18 563 }
8dd014adf David Stevens 2010-07-27 564 vhost_discard_vq_desc(vq, 1);
3a4d5c94e Michael S. Tsirkin 2010-01-14 565 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 566 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 567 if (err != len)
95c0ec6a9 Michael S. Tsirkin 2010-06-24 568 pr_debug("Truncated TX packet: "
3a4d5c94e Michael S. Tsirkin 2010-01-14 569 " len %d != %zd\n", err, len);
cedb9bdce Michael S. Tsirkin 2012-12-06 570 if (!zcopy_used)
3a4d5c94e Michael S. Tsirkin 2010-01-14 571 vhost_add_used_and_signal(&net->dev, vq, head, 0);
c8fb217af Jason Wang 2012-05-02 572 else
eaae8132e Michael S. Tsirkin 2012-11-01 573 vhost_zerocopy_signal_used(net, vq);
eaae8132e Michael S. Tsirkin 2012-11-01 574 vhost_net_tx_packet(net);
3a4d5c94e Michael S. Tsirkin 2010-01-14 575 if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
3a4d5c94e Michael S. Tsirkin 2010-01-14 576 vhost_poll_queue(&vq->poll);
3a4d5c94e Michael S. Tsirkin 2010-01-14 577 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 578 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 579 }
2e26af79b Asias He 2013-05-07 580 out:
3a4d5c94e Michael S. Tsirkin 2010-01-14 581 mutex_unlock(&vq->mutex);
3a4d5c94e Michael S. Tsirkin 2010-01-14 582 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 583
:::::: The code at line 536 was first introduced by commit
:::::: 1f8b977ab32dc5d148f103326e80d9097f1cefb5 sock: enable MSG_ZEROCOPY
:::::: TO: Willem de Bruijn <willemb@google.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30263 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 2/2] net: convert (struct ubuf_info)->refcnt to refcount_t
From: kbuild test robot @ 2017-09-02 21:58 UTC (permalink / raw)
To: Eric Dumazet
Cc: kbuild-all, David S . Miller, netdev, Willem de Bruijn,
Eric Dumazet, Eric Dumazet
In-Reply-To: <20170831203013.9219-3-edumazet@google.com>
[-- Attachment #1: Type: text/plain, Size: 11970 bytes --]
Hi Eric,
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/net-ubuf_info-refcnt-conversion/20170903-043506
config: i386-randconfig-i1-201736 (attached as .config)
compiler: gcc-4.8 (Debian 4.8.4-1) 4.8.4
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All warnings (new ones prefixed by >>):
drivers//vhost/net.c: In function 'handle_tx':
>> drivers//vhost/net.c:536:4: warning: passing argument 1 of 'atomic_set' from incompatible pointer type [enabled by default]
atomic_set(&ubuf->refcnt, 1);
^
In file included from include/linux/atomic.h:4:0,
from arch/x86/include/asm/thread_info.h:53,
from include/linux/thread_info.h:37,
from arch/x86/include/asm/preempt.h:6,
from include/linux/preempt.h:80,
from include/linux/spinlock.h:50,
from include/linux/wait.h:8,
from include/linux/eventfd.h:12,
from drivers//vhost/net.c:10:
arch/x86/include/asm/atomic.h:36:29: note: expected 'struct atomic_t *' but argument is of type 'struct refcount_t *'
static __always_inline void atomic_set(atomic_t *v, int i)
^
vim +/atomic_set +536 drivers//vhost/net.c
0ed005ce0 Jason Wang 2017-01-18 442
3a4d5c94e Michael S. Tsirkin 2010-01-14 443 /* Expects to be always run from workqueue - which acts as
3a4d5c94e Michael S. Tsirkin 2010-01-14 444 * read-size critical section for our kind of RCU. */
3a4d5c94e Michael S. Tsirkin 2010-01-14 445 static void handle_tx(struct vhost_net *net)
3a4d5c94e Michael S. Tsirkin 2010-01-14 446 {
2839400f8 Asias He 2013-04-27 447 struct vhost_net_virtqueue *nvq = &net->vqs[VHOST_NET_VQ_TX];
81f95a558 Michael S. Tsirkin 2013-04-28 448 struct vhost_virtqueue *vq = &nvq->vq;
98a527aac Al Viro 2014-12-10 449 unsigned out, in;
d5675bd20 Michael S. Tsirkin 2010-06-24 450 int head;
3a4d5c94e Michael S. Tsirkin 2010-01-14 451 struct msghdr msg = {
3a4d5c94e Michael S. Tsirkin 2010-01-14 452 .msg_name = NULL,
3a4d5c94e Michael S. Tsirkin 2010-01-14 453 .msg_namelen = 0,
3a4d5c94e Michael S. Tsirkin 2010-01-14 454 .msg_control = NULL,
3a4d5c94e Michael S. Tsirkin 2010-01-14 455 .msg_controllen = 0,
3a4d5c94e Michael S. Tsirkin 2010-01-14 456 .msg_flags = MSG_DONTWAIT,
3a4d5c94e Michael S. Tsirkin 2010-01-14 457 };
3a4d5c94e Michael S. Tsirkin 2010-01-14 458 size_t len, total_len = 0;
70181d512 Jason Wang 2013-04-10 459 int err;
3a4d5c94e Michael S. Tsirkin 2010-01-14 460 size_t hdr_size;
28457ee69 Arnd Bergmann 2010-03-09 461 struct socket *sock;
fe729a57c Asias He 2013-05-06 462 struct vhost_net_ubuf_ref *uninitialized_var(ubufs);
cedb9bdce Michael S. Tsirkin 2012-12-06 463 bool zcopy, zcopy_used;
28457ee69 Arnd Bergmann 2010-03-09 464
2e26af79b Asias He 2013-05-07 465 mutex_lock(&vq->mutex);
2e26af79b Asias He 2013-05-07 466 sock = vq->private_data;
3a4d5c94e Michael S. Tsirkin 2010-01-14 467 if (!sock)
2e26af79b Asias He 2013-05-07 468 goto out;
3a4d5c94e Michael S. Tsirkin 2010-01-14 469
6b1e6cc78 Jason Wang 2016-06-23 470 if (!vq_iotlb_prefetch(vq))
6b1e6cc78 Jason Wang 2016-06-23 471 goto out;
6b1e6cc78 Jason Wang 2016-06-23 472
8ea8cf89e Michael S. Tsirkin 2011-05-20 473 vhost_disable_notify(&net->dev, vq);
3a4d5c94e Michael S. Tsirkin 2010-01-14 474
81f95a558 Michael S. Tsirkin 2013-04-28 475 hdr_size = nvq->vhost_hlen;
2839400f8 Asias He 2013-04-27 476 zcopy = nvq->ubufs;
3a4d5c94e Michael S. Tsirkin 2010-01-14 477
3a4d5c94e Michael S. Tsirkin 2010-01-14 478 for (;;) {
bab632d69 Michael S. Tsirkin 2011-07-18 479 /* Release DMAs done buffers first */
bab632d69 Michael S. Tsirkin 2011-07-18 480 if (zcopy)
eaae8132e Michael S. Tsirkin 2012-11-01 481 vhost_zerocopy_signal_used(net, vq);
bab632d69 Michael S. Tsirkin 2011-07-18 482
f7c6be404 Jason Wang 2013-09-02 483 /* If more outstanding DMAs, queue the work.
f7c6be404 Jason Wang 2013-09-02 484 * Handle upend_idx wrap around
f7c6be404 Jason Wang 2013-09-02 485 */
0ed005ce0 Jason Wang 2017-01-18 486 if (unlikely(vhost_exceeds_maxpend(net)))
f7c6be404 Jason Wang 2013-09-02 487 break;
f7c6be404 Jason Wang 2013-09-02 488
030881372 Jason Wang 2016-03-04 489 head = vhost_net_tx_get_vq_desc(net, vq, vq->iov,
3a4d5c94e Michael S. Tsirkin 2010-01-14 490 ARRAY_SIZE(vq->iov),
030881372 Jason Wang 2016-03-04 491 &out, &in);
d5675bd20 Michael S. Tsirkin 2010-06-24 492 /* On error, stop handling until the next kick. */
7b3384fc3 Michael S. Tsirkin 2010-07-01 493 if (unlikely(head < 0))
d5675bd20 Michael S. Tsirkin 2010-06-24 494 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 495 /* Nothing new? Wait for eventfd to tell us they refilled. */
3a4d5c94e Michael S. Tsirkin 2010-01-14 496 if (head == vq->num) {
8ea8cf89e Michael S. Tsirkin 2011-05-20 497 if (unlikely(vhost_enable_notify(&net->dev, vq))) {
8ea8cf89e Michael S. Tsirkin 2011-05-20 498 vhost_disable_notify(&net->dev, vq);
3a4d5c94e Michael S. Tsirkin 2010-01-14 499 continue;
3a4d5c94e Michael S. Tsirkin 2010-01-14 500 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 501 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 502 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 503 if (in) {
3a4d5c94e Michael S. Tsirkin 2010-01-14 504 vq_err(vq, "Unexpected descriptor format for TX: "
3a4d5c94e Michael S. Tsirkin 2010-01-14 505 "out %d, int %d\n", out, in);
3a4d5c94e Michael S. Tsirkin 2010-01-14 506 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 507 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 508 /* Skip header. TODO: support TSO. */
3a4d5c94e Michael S. Tsirkin 2010-01-14 509 len = iov_length(vq->iov, out);
c0371da60 Al Viro 2014-11-24 510 iov_iter_init(&msg.msg_iter, WRITE, vq->iov, out, len);
98a527aac Al Viro 2014-12-10 511 iov_iter_advance(&msg.msg_iter, hdr_size);
3a4d5c94e Michael S. Tsirkin 2010-01-14 512 /* Sanity check */
01e97e651 Al Viro 2014-12-15 513 if (!msg_data_left(&msg)) {
3a4d5c94e Michael S. Tsirkin 2010-01-14 514 vq_err(vq, "Unexpected header len for TX: "
3a4d5c94e Michael S. Tsirkin 2010-01-14 515 "%zd expected %zd\n",
98a527aac Al Viro 2014-12-10 516 len, hdr_size);
3a4d5c94e Michael S. Tsirkin 2010-01-14 517 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 518 }
01e97e651 Al Viro 2014-12-15 519 len = msg_data_left(&msg);
ce21a0291 Jason Wang 2013-09-02 520
ce21a0291 Jason Wang 2013-09-02 521 zcopy_used = zcopy && len >= VHOST_GOODCOPY_LEN
ce21a0291 Jason Wang 2013-09-02 522 && (nvq->upend_idx + 1) % UIO_MAXIOV !=
ce21a0291 Jason Wang 2013-09-02 523 nvq->done_idx
ce21a0291 Jason Wang 2013-09-02 524 && vhost_net_tx_select_zcopy(net);
cedb9bdce Michael S. Tsirkin 2012-12-06 525
bab632d69 Michael S. Tsirkin 2011-07-18 526 /* use msg_control to pass vhost zerocopy ubuf info to skb */
cedb9bdce Michael S. Tsirkin 2012-12-06 527 if (zcopy_used) {
46aa92d1b Michael S. Tsirkin 2013-03-17 528 struct ubuf_info *ubuf;
2839400f8 Asias He 2013-04-27 529 ubuf = nvq->ubuf_info + nvq->upend_idx;
bab632d69 Michael S. Tsirkin 2011-07-18 530
8b38694a2 Michael S. Tsirkin 2014-10-24 531 vq->heads[nvq->upend_idx].id = cpu_to_vhost32(vq, head);
ce21a0291 Jason Wang 2013-09-02 532 vq->heads[nvq->upend_idx].len = VHOST_DMA_IN_PROGRESS;
bab632d69 Michael S. Tsirkin 2011-07-18 533 ubuf->callback = vhost_zerocopy_callback;
2839400f8 Asias He 2013-04-27 534 ubuf->ctx = nvq->ubufs;
2839400f8 Asias He 2013-04-27 535 ubuf->desc = nvq->upend_idx;
1f8b977ab Willem de Bruijn 2017-08-03 @536 atomic_set(&ubuf->refcnt, 1);
bab632d69 Michael S. Tsirkin 2011-07-18 537 msg.msg_control = ubuf;
bab632d69 Michael S. Tsirkin 2011-07-18 538 msg.msg_controllen = sizeof(ubuf);
2839400f8 Asias He 2013-04-27 539 ubufs = nvq->ubufs;
0ad8b480d Michael S. Tsirkin 2014-02-13 540 atomic_inc(&ubufs->refcount);
2839400f8 Asias He 2013-04-27 541 nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV;
ce21a0291 Jason Wang 2013-09-02 542 } else {
4364d5f96 Jason Wang 2013-06-05 543 msg.msg_control = NULL;
ce21a0291 Jason Wang 2013-09-02 544 ubufs = NULL;
ce21a0291 Jason Wang 2013-09-02 545 }
0ed005ce0 Jason Wang 2017-01-18 546
0ed005ce0 Jason Wang 2017-01-18 547 total_len += len;
0ed005ce0 Jason Wang 2017-01-18 548 if (total_len < VHOST_NET_WEIGHT &&
0ed005ce0 Jason Wang 2017-01-18 549 !vhost_vq_avail_empty(&net->dev, vq) &&
0ed005ce0 Jason Wang 2017-01-18 550 likely(!vhost_exceeds_maxpend(net))) {
0ed005ce0 Jason Wang 2017-01-18 551 msg.msg_flags |= MSG_MORE;
0ed005ce0 Jason Wang 2017-01-18 552 } else {
0ed005ce0 Jason Wang 2017-01-18 553 msg.msg_flags &= ~MSG_MORE;
0ed005ce0 Jason Wang 2017-01-18 554 }
0ed005ce0 Jason Wang 2017-01-18 555
3a4d5c94e Michael S. Tsirkin 2010-01-14 556 /* TODO: Check specific error and bomb out unless ENOBUFS? */
1b7841404 Ying Xue 2015-03-02 557 err = sock->ops->sendmsg(sock, &msg, len);
3a4d5c94e Michael S. Tsirkin 2010-01-14 558 if (unlikely(err < 0)) {
cedb9bdce Michael S. Tsirkin 2012-12-06 559 if (zcopy_used) {
fe729a57c Asias He 2013-05-06 560 vhost_net_ubuf_put(ubufs);
2839400f8 Asias He 2013-04-27 561 nvq->upend_idx = ((unsigned)nvq->upend_idx - 1)
2839400f8 Asias He 2013-04-27 562 % UIO_MAXIOV;
bab632d69 Michael S. Tsirkin 2011-07-18 563 }
8dd014adf David Stevens 2010-07-27 564 vhost_discard_vq_desc(vq, 1);
3a4d5c94e Michael S. Tsirkin 2010-01-14 565 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 566 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 567 if (err != len)
95c0ec6a9 Michael S. Tsirkin 2010-06-24 568 pr_debug("Truncated TX packet: "
3a4d5c94e Michael S. Tsirkin 2010-01-14 569 " len %d != %zd\n", err, len);
cedb9bdce Michael S. Tsirkin 2012-12-06 570 if (!zcopy_used)
3a4d5c94e Michael S. Tsirkin 2010-01-14 571 vhost_add_used_and_signal(&net->dev, vq, head, 0);
c8fb217af Jason Wang 2012-05-02 572 else
eaae8132e Michael S. Tsirkin 2012-11-01 573 vhost_zerocopy_signal_used(net, vq);
eaae8132e Michael S. Tsirkin 2012-11-01 574 vhost_net_tx_packet(net);
3a4d5c94e Michael S. Tsirkin 2010-01-14 575 if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
3a4d5c94e Michael S. Tsirkin 2010-01-14 576 vhost_poll_queue(&vq->poll);
3a4d5c94e Michael S. Tsirkin 2010-01-14 577 break;
3a4d5c94e Michael S. Tsirkin 2010-01-14 578 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 579 }
2e26af79b Asias He 2013-05-07 580 out:
3a4d5c94e Michael S. Tsirkin 2010-01-14 581 mutex_unlock(&vq->mutex);
3a4d5c94e Michael S. Tsirkin 2010-01-14 582 }
3a4d5c94e Michael S. Tsirkin 2010-01-14 583
:::::: The code at line 536 was first introduced by commit
:::::: 1f8b977ab32dc5d148f103326e80d9097f1cefb5 sock: enable MSG_ZEROCOPY
:::::: TO: Willem de Bruijn <willemb@google.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32722 bytes --]
^ permalink raw reply
* [patch net-next v2 21/21] mlxsw: spectrum_router: Support GRE tunnels
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
This patch introduces callbacks and tunnel type to offload GRE tunnels.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_ipip.c | 176 +++++++++++++++++++++
.../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 1 +
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 26 +++
.../net/ethernet/mellanox/mlxsw/spectrum_router.h | 4 +
4 files changed, 207 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
index 20b0b96..702fe94 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
@@ -32,7 +32,183 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <net/ip_tunnels.h>
+
#include "spectrum_ipip.h"
+static bool
+mlxsw_sp_ipip_netdev_has_ikey(const struct net_device *ol_dev)
+{
+ struct ip_tunnel *tun = netdev_priv(ol_dev);
+
+ return !!(tun->parms.i_flags & TUNNEL_KEY);
+}
+
+static bool
+mlxsw_sp_ipip_netdev_has_okey(const struct net_device *ol_dev)
+{
+ struct ip_tunnel *tun = netdev_priv(ol_dev);
+
+ return !!(tun->parms.o_flags & TUNNEL_KEY);
+}
+
+static u32 mlxsw_sp_ipip_netdev_ikey(const struct net_device *ol_dev)
+{
+ struct ip_tunnel *tun = netdev_priv(ol_dev);
+
+ return mlxsw_sp_ipip_netdev_has_ikey(ol_dev) ?
+ be32_to_cpu(tun->parms.i_key) : 0;
+}
+
+static u32 mlxsw_sp_ipip_netdev_okey(const struct net_device *ol_dev)
+{
+ struct ip_tunnel *tun = netdev_priv(ol_dev);
+
+ return mlxsw_sp_ipip_netdev_has_okey(ol_dev) ?
+ be32_to_cpu(tun->parms.o_key) : 0;
+}
+
+static int
+mlxsw_sp_ipip_nexthop_update_gre4(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
+ __be32 daddr4 = mlxsw_sp_ipip_netdev_daddr4(ipip_entry->ol_dev);
+ char ratr_pl[MLXSW_REG_RATR_LEN];
+
+ mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY,
+ true, MLXSW_REG_RATR_TYPE_IPIP,
+ adj_index, rif_index);
+ mlxsw_reg_ratr_ipip4_entry_pack(ratr_pl, be32_to_cpu(daddr4));
+
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
+}
+
+static int
+mlxsw_sp_ipip_fib_entry_op_gre4_rtdp(struct mlxsw_sp *mlxsw_sp,
+ u32 tunnel_index,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ bool has_ikey = mlxsw_sp_ipip_netdev_has_ikey(ipip_entry->ol_dev);
+ u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
+ u32 ikey = mlxsw_sp_ipip_netdev_ikey(ipip_entry->ol_dev);
+ char rtdp_pl[MLXSW_REG_RTDP_LEN];
+ unsigned int type_check;
+ u32 daddr4;
+
+ mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index);
+
+ type_check = has_ikey ?
+ MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY :
+ MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE;
+
+ /* Linux demuxes tunnels based on packet SIP (which must match tunnel
+ * remote IP). Thus configure decap so that it filters out packets that
+ * are not IPv4 or have the wrong SIP. IPIP_DECAP_ERROR trap is
+ * generated for packets that fail this criterion. Linux then handles
+ * such packets in slow path and generates ICMP destination unreachable.
+ */
+ daddr4 = be32_to_cpu(mlxsw_sp_ipip_netdev_daddr4(ipip_entry->ol_dev));
+ mlxsw_reg_rtdp_ipip4_pack(rtdp_pl, rif_index,
+ MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV4,
+ type_check, has_ikey, daddr4, ikey);
+
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
+}
+
+static int
+mlxsw_sp_ipip_fib_entry_op_gre4_ralue(struct mlxsw_sp *mlxsw_sp,
+ u32 dip, u8 prefix_len, u16 ul_vr_id,
+ enum mlxsw_reg_ralue_op op,
+ u32 tunnel_index)
+{
+ char ralue_pl[MLXSW_REG_RALUE_LEN];
+
+ mlxsw_reg_ralue_pack4(ralue_pl, MLXSW_REG_RALXX_PROTOCOL_IPV4, op,
+ ul_vr_id, prefix_len, dip);
+ mlxsw_reg_ralue_act_ip2me_tun_pack(ralue_pl, tunnel_index);
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
+}
+
+static int mlxsw_sp_ipip_fib_entry_op_gre4(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_ipip_entry *ipip_entry,
+ enum mlxsw_reg_ralue_op op,
+ u32 tunnel_index)
+{
+ u16 ul_vr_id = mlxsw_sp_ipip_lb_ul_vr_id(ipip_entry->ol_lb);
+ __be32 dip;
+ int err;
+
+ err = mlxsw_sp_ipip_fib_entry_op_gre4_rtdp(mlxsw_sp, tunnel_index,
+ ipip_entry);
+ if (err)
+ return err;
+
+ dip = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV4,
+ ipip_entry->ol_dev).addr4;
+ return mlxsw_sp_ipip_fib_entry_op_gre4_ralue(mlxsw_sp, be32_to_cpu(dip),
+ 32, ul_vr_id, op,
+ tunnel_index);
+}
+
+static bool mlxsw_sp_ipip_tunnel_complete(enum mlxsw_sp_l3proto proto,
+ const struct net_device *ol_dev)
+{
+ union mlxsw_sp_l3addr saddr = mlxsw_sp_ipip_netdev_saddr(proto, ol_dev);
+ union mlxsw_sp_l3addr daddr = mlxsw_sp_ipip_netdev_daddr(proto, ol_dev);
+ union mlxsw_sp_l3addr naddr = {0};
+
+ /* Tunnels with unset local or remote address are valid in Linux and
+ * used for lightweight tunnels (LWT) and Non-Broadcast Multi-Access
+ * (NBMA) tunnels. In principle these can be offloaded, but the driver
+ * currently doesn't support this. So punt.
+ */
+ return memcmp(&saddr, &naddr, sizeof(naddr)) &&
+ memcmp(&daddr, &naddr, sizeof(naddr));
+}
+
+static bool mlxsw_sp_ipip_can_offload_gre4(const struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *ol_dev,
+ enum mlxsw_sp_l3proto ol_proto)
+{
+ struct ip_tunnel *tunnel = netdev_priv(ol_dev);
+ __be16 okflags = TUNNEL_KEY; /* We can't offload any other features. */
+ bool inherit_ttl = tunnel->parms.iph.ttl == 0;
+ bool inherit_tos = tunnel->parms.iph.tos & 0x1;
+
+ return (tunnel->parms.i_flags & ~okflags) == 0 &&
+ (tunnel->parms.o_flags & ~okflags) == 0 &&
+ inherit_ttl && inherit_tos &&
+ mlxsw_sp_ipip_tunnel_complete(MLXSW_SP_L3_PROTO_IPV4, ol_dev);
+}
+
+static struct mlxsw_sp_rif_ipip_lb_config
+mlxsw_sp_ipip_ol_loopback_config_gre4(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *ol_dev)
+{
+ enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
+
+ lb_ipipt = mlxsw_sp_ipip_netdev_has_okey(ol_dev) ?
+ MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP :
+ MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP;
+ return (struct mlxsw_sp_rif_ipip_lb_config){
+ .lb_ipipt = lb_ipipt,
+ .okey = mlxsw_sp_ipip_netdev_okey(ol_dev),
+ .ul_protocol = MLXSW_SP_L3_PROTO_IPV4,
+ .saddr = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV4,
+ ol_dev),
+ };
+}
+
+static const struct mlxsw_sp_ipip_ops mlxsw_sp_ipip_gre4_ops = {
+ .dev_type = ARPHRD_IPGRE,
+ .ul_proto = MLXSW_SP_L3_PROTO_IPV4,
+ .nexthop_update = mlxsw_sp_ipip_nexthop_update_gre4,
+ .fib_entry_op = mlxsw_sp_ipip_fib_entry_op_gre4,
+ .can_offload = mlxsw_sp_ipip_can_offload_gre4,
+ .ol_loopback_config = mlxsw_sp_ipip_ol_loopback_config_gre4,
+};
+
const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[] = {
+ [MLXSW_SP_IPIP_TYPE_GRE4] = &mlxsw_sp_ipip_gre4_ops,
};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
index cd986bd..1c2db83 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
@@ -39,6 +39,7 @@
#include <net/ip_fib.h>
enum mlxsw_sp_ipip_type {
+ MLXSW_SP_IPIP_TYPE_GRE4,
MLXSW_SP_IPIP_TYPE_MAX,
};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 6068eea..f0fb898 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1020,6 +1020,32 @@ mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
};
}
+__be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev)
+{
+ struct ip_tunnel *tun = netdev_priv(ol_dev);
+
+ return tun->parms.iph.daddr;
+}
+
+union mlxsw_sp_l3addr
+mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto,
+ const struct net_device *ol_dev)
+{
+ switch (proto) {
+ case MLXSW_SP_L3_PROTO_IPV4:
+ return (union mlxsw_sp_l3addr) {
+ .addr4 = mlxsw_sp_ipip_netdev_daddr4(ol_dev),
+ };
+ case MLXSW_SP_L3_PROTO_IPV6:
+ break;
+ };
+
+ WARN_ON(1);
+ return (union mlxsw_sp_l3addr) {
+ .addr4 = 0,
+ };
+}
+
static bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1,
const union mlxsw_sp_l3addr *addr2)
{
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index 9632476..345fcc4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -103,5 +103,9 @@ bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry);
union mlxsw_sp_l3addr
mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
const struct net_device *ol_dev);
+union mlxsw_sp_l3addr
+mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto,
+ const struct net_device *ol_dev);
+__be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev);
#endif /* _MLXSW_ROUTER_H_*/
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 20/21] mlxsw: spectrum_router: Add loopback accessors
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
struct mlxsw_sp_rif is a router-private structure, and therefore
everything related to it is as well: parameters, and derived RIF types
including loopbacks. IPIP module needs access to some details of
loopback interfaces, but exporting all the RIF shebang would create too
large an interface.
So instead export just the bare minimum necessary: accessors for RIF
index and underlay VRF ID.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 ++++++++++
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h | 3 +++
2 files changed, 13 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 2189cf0..6068eea 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -5007,6 +5007,16 @@ u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif)
return rif->rif_index;
}
+u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
+{
+ return lb_rif->common.rif_index;
+}
+
+u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
+{
+ return lb_rif->ul_vr_id;
+}
+
int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif)
{
return rif->dev->ifindex;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index 4276f5f..9632476 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -48,6 +48,7 @@ union mlxsw_sp_l3addr {
struct in6_addr addr6;
};
+struct mlxsw_sp_rif_ipip_lb;
struct mlxsw_sp_rif_ipip_lb_config {
enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
u32 okey;
@@ -65,6 +66,8 @@ struct mlxsw_sp_neigh_entry;
struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
u16 rif_index);
u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif);
+u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif);
+u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif);
int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif);
int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif,
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 19/21] mlxsw: spectrum: Register for IPIP_DECAP_ERROR trap
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
These traps are generated for packets that fail checks for source IP,
encapsulation type, or GRE key. Trap these packets to CPU for follow-up
handling by the kernel, which will send ICMP destination unreachable
responses.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 1 +
drivers/net/ethernet/mellanox/mlxsw/trap.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 992cbfa..ed7cd6c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3400,6 +3400,7 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
MLXSW_SP_RXL_MARK(HOST_MISS_IPV6, TRAP_TO_CPU, HOST_MISS, false),
MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, TRAP_TO_CPU, ROUTER_EXP, false),
MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false),
+ MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false),
/* PKT Sample trap */
MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU,
false, SP_IP2ME, DISCARD),
diff --git a/drivers/net/ethernet/mellanox/mlxsw/trap.h b/drivers/net/ethernet/mellanox/mlxsw/trap.h
index 6165239..f396a1f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/trap.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/trap.h
@@ -85,6 +85,7 @@ enum {
MLXSW_TRAP_ID_HOST_MISS_IPV4 = 0x90,
MLXSW_TRAP_ID_IPV6_MC_LINK_LOCAL_DEST = 0x91,
MLXSW_TRAP_ID_HOST_MISS_IPV6 = 0x92,
+ MLXSW_TRAP_ID_IPIP_DECAP_ERROR = 0xB1,
MLXSW_TRAP_ID_ROUTER_ALERT_IPV4 = 0xD6,
MLXSW_TRAP_ID_ROUTER_ALERT_IPV6 = 0xD7,
MLXSW_TRAP_ID_ACL0 = 0x1C0,
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 18/21] mlxsw: spectrum_router: Use existing decap route
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
The local route that points at IPIP's underlay device (decap route) can
be present long before the GRE device. Thus when an encap route is
added, it's necessary to look inside the underlay FIB if the decap route
is already present. If so, the current trap offload needs to be
withdrawn and replaced with a decap offload.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 80 ++++++++++++++++++++--
1 file changed, 76 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 0d09f81..2189cf0 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1072,6 +1072,9 @@ static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_kvdl_free(mlxsw_sp, fib_entry->decap.tunnel_index);
}
+static struct mlxsw_sp_fib_node *
+mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr,
+ size_t addr_len, unsigned char prefix_len);
static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry);
@@ -1087,6 +1090,73 @@ mlxsw_sp_ipip_entry_demote_decap(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
}
+static void
+mlxsw_sp_ipip_entry_promote_decap(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_ipip_entry *ipip_entry,
+ struct mlxsw_sp_fib_entry *decap_fib_entry)
+{
+ if (mlxsw_sp_fib_entry_decap_init(mlxsw_sp, decap_fib_entry,
+ ipip_entry))
+ return;
+ decap_fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP;
+
+ if (mlxsw_sp_fib_entry_update(mlxsw_sp, decap_fib_entry))
+ mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry);
+}
+
+/* Given an IPIP entry, find the corresponding decap route. */
+static struct mlxsw_sp_fib_entry *
+mlxsw_sp_ipip_entry_find_decap(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ static struct mlxsw_sp_fib_node *fib_node;
+ const struct mlxsw_sp_ipip_ops *ipip_ops;
+ struct mlxsw_sp_fib_entry *fib_entry;
+ unsigned char saddr_prefix_len;
+ union mlxsw_sp_l3addr saddr;
+ struct mlxsw_sp_fib *ul_fib;
+ struct mlxsw_sp_vr *ul_vr;
+ const void *saddrp;
+ size_t saddr_len;
+ u32 ul_tb_id;
+ u32 saddr4;
+
+ ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt];
+
+ ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev);
+ ul_vr = mlxsw_sp_vr_find(mlxsw_sp, ul_tb_id);
+ if (!ul_vr)
+ return NULL;
+
+ ul_fib = mlxsw_sp_vr_fib(ul_vr, ipip_ops->ul_proto);
+ saddr = mlxsw_sp_ipip_netdev_saddr(ipip_ops->ul_proto,
+ ipip_entry->ol_dev);
+
+ switch (ipip_ops->ul_proto) {
+ case MLXSW_SP_L3_PROTO_IPV4:
+ saddr4 = be32_to_cpu(saddr.addr4);
+ saddrp = &saddr4;
+ saddr_len = 4;
+ saddr_prefix_len = 32;
+ break;
+ case MLXSW_SP_L3_PROTO_IPV6:
+ WARN_ON(1);
+ return NULL;
+ }
+
+ fib_node = mlxsw_sp_fib_node_lookup(ul_fib, saddrp, saddr_len,
+ saddr_prefix_len);
+ if (!fib_node || list_empty(&fib_node->entry_list))
+ return NULL;
+
+ fib_entry = list_first_entry(&fib_node->entry_list,
+ struct mlxsw_sp_fib_entry, list);
+ if (fib_entry->type != MLXSW_SP_FIB_ENTRY_TYPE_TRAP)
+ return NULL;
+
+ return fib_entry;
+}
+
static struct mlxsw_sp_ipip_entry *
mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt,
@@ -1094,6 +1164,7 @@ mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp,
{
u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ol_dev);
struct mlxsw_sp_router *router = mlxsw_sp->router;
+ struct mlxsw_sp_fib_entry *decap_fib_entry;
struct mlxsw_sp_ipip_entry *ipip_entry;
enum mlxsw_sp_l3proto ul_proto;
union mlxsw_sp_l3addr saddr;
@@ -1118,6 +1189,11 @@ mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp,
if (IS_ERR(ipip_entry))
return ipip_entry;
+ decap_fib_entry = mlxsw_sp_ipip_entry_find_decap(mlxsw_sp, ipip_entry);
+ if (decap_fib_entry)
+ mlxsw_sp_ipip_entry_promote_decap(mlxsw_sp, ipip_entry,
+ decap_fib_entry);
+
list_add_tail(&ipip_entry->ipip_list_node,
&mlxsw_sp->router->ipip_list);
@@ -3259,10 +3335,6 @@ static void mlxsw_sp_fib4_entry_destroy(struct mlxsw_sp *mlxsw_sp,
kfree(fib4_entry);
}
-static struct mlxsw_sp_fib_node *
-mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr,
- size_t addr_len, unsigned char prefix_len);
-
static struct mlxsw_sp_fib4_entry *
mlxsw_sp_fib4_entry_lookup(struct mlxsw_sp *mlxsw_sp,
const struct fib_entry_notifier_info *fen_info)
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 17/21] mlxsw: spectrum_router: Support IPv4 underlay decap
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
Unlike encapsulation, which is represented by a next hop forwarding to
an IPIP tunnel, decapsulation is a type of local route. It is created
for local routes whose prefix corresponds to the local address of one of
offloaded IPIP tunnels. When the tunnel is removed (i.e. all the encap
next hops are removed), the decap offload is migrated back to a trap for
resolution in slow path.
This patch assumes that decap route is already present when encap route
is added. A follow-up patch will fix this issue.
Note that this patch only supports IPv4 underlay. Support for IPv6
underlay will be subject to follow-up work apart from this patchset.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 7 +
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 141 ++++++++++++++++++++-
.../net/ethernet/mellanox/mlxsw/spectrum_router.h | 3 +
3 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
index 7b40aa2..cd986bd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
@@ -36,6 +36,7 @@
#define _MLXSW_IPIP_H_
#include "spectrum_router.h"
+#include <net/ip_fib.h>
enum mlxsw_sp_ipip_type {
MLXSW_SP_IPIP_TYPE_MAX,
@@ -46,6 +47,7 @@ struct mlxsw_sp_ipip_entry {
struct net_device *ol_dev; /* Overlay. */
struct mlxsw_sp_rif_ipip_lb *ol_lb;
unsigned int ref_count; /* Number of next hops using the tunnel. */
+ struct mlxsw_sp_fib_entry *decap_fib_entry;
struct list_head ipip_list_node;
};
@@ -64,6 +66,11 @@ struct mlxsw_sp_ipip_ops {
struct mlxsw_sp_rif_ipip_lb_config
(*ol_loopback_config)(struct mlxsw_sp *mlxsw_sp,
const struct net_device *ol_dev);
+
+ int (*fib_entry_op)(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_ipip_entry *ipip_entry,
+ enum mlxsw_reg_ralue_op op,
+ u32 tunnel_index);
};
extern const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[];
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 05afd53..0d09f81 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -381,6 +381,14 @@ enum mlxsw_sp_fib_entry_type {
MLXSW_SP_FIB_ENTRY_TYPE_REMOTE,
MLXSW_SP_FIB_ENTRY_TYPE_LOCAL,
MLXSW_SP_FIB_ENTRY_TYPE_TRAP,
+
+ /* This is a special case of local delivery, where a packet should be
+ * decapsulated on reception. Note that there is no corresponding ENCAP,
+ * because that's a type of next hop, not of FIB entry. (There can be
+ * several next hops in a REMOTE entry, and some of them may be
+ * encapsulating entries.)
+ */
+ MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP,
};
struct mlxsw_sp_nexthop_group;
@@ -394,12 +402,18 @@ struct mlxsw_sp_fib_node {
struct mlxsw_sp_fib_key key;
};
+struct mlxsw_sp_fib_entry_decap {
+ struct mlxsw_sp_ipip_entry *ipip_entry;
+ u32 tunnel_index;
+};
+
struct mlxsw_sp_fib_entry {
struct list_head list;
struct mlxsw_sp_fib_node *fib_node;
enum mlxsw_sp_fib_entry_type type;
struct list_head nexthop_group_node;
struct mlxsw_sp_nexthop_group *nh_group;
+ struct mlxsw_sp_fib_entry_decap decap; /* Valid for decap entries. */
};
struct mlxsw_sp_fib4_entry {
@@ -1031,6 +1045,48 @@ mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_l3addr_eq(&tun_saddr, &saddr);
}
+static int
+mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_fib_entry *fib_entry,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ u32 tunnel_index;
+ int err;
+
+ err = mlxsw_sp_kvdl_alloc(mlxsw_sp, 1, &tunnel_index);
+ if (err)
+ return err;
+
+ ipip_entry->decap_fib_entry = fib_entry;
+ fib_entry->decap.ipip_entry = ipip_entry;
+ fib_entry->decap.tunnel_index = tunnel_index;
+ return 0;
+}
+
+static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_fib_entry *fib_entry)
+{
+ /* Unlink this node from the IPIP entry that it's the decap entry of. */
+ fib_entry->decap.ipip_entry->decap_fib_entry = NULL;
+ fib_entry->decap.ipip_entry = NULL;
+ mlxsw_sp_kvdl_free(mlxsw_sp, fib_entry->decap.tunnel_index);
+}
+
+static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_fib_entry *fib_entry);
+
+static void
+mlxsw_sp_ipip_entry_demote_decap(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ struct mlxsw_sp_fib_entry *fib_entry = ipip_entry->decap_fib_entry;
+
+ mlxsw_sp_fib_entry_decap_fini(mlxsw_sp, fib_entry);
+ fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
+
+ mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
+}
+
static struct mlxsw_sp_ipip_entry *
mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt,
@@ -1076,10 +1132,51 @@ mlxsw_sp_ipip_entry_put(struct mlxsw_sp *mlxsw_sp,
{
if (--ipip_entry->ref_count == 0) {
list_del(&ipip_entry->ipip_list_node);
+ if (ipip_entry->decap_fib_entry)
+ mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry);
mlxsw_sp_ipip_entry_destroy(ipip_entry);
}
}
+static bool
+mlxsw_sp_ipip_entry_matches_decap(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *ul_dev,
+ enum mlxsw_sp_l3proto ul_proto,
+ union mlxsw_sp_l3addr ul_dip,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ u32 ul_tb_id = l3mdev_fib_table(ul_dev) ? : RT_TABLE_MAIN;
+ enum mlxsw_sp_ipip_type ipipt = ipip_entry->ipipt;
+ struct net_device *ipip_ul_dev;
+
+ if (mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto != ul_proto)
+ return false;
+
+ ipip_ul_dev = __mlxsw_sp_ipip_netdev_ul_dev_get(ipip_entry->ol_dev);
+ return mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, ul_dip,
+ ul_tb_id, ipip_entry) &&
+ (!ipip_ul_dev || ipip_ul_dev == ul_dev);
+}
+
+/* Given decap parameters, find the corresponding IPIP entry. */
+static struct mlxsw_sp_ipip_entry *
+mlxsw_sp_ipip_entry_find_by_decap(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *ul_dev,
+ enum mlxsw_sp_l3proto ul_proto,
+ union mlxsw_sp_l3addr ul_dip)
+{
+ struct mlxsw_sp_ipip_entry *ipip_entry;
+
+ list_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list,
+ ipip_list_node)
+ if (mlxsw_sp_ipip_entry_matches_decap(mlxsw_sp, ul_dev,
+ ul_proto, ul_dip,
+ ipip_entry))
+ return ipip_entry;
+
+ return NULL;
+}
+
struct mlxsw_sp_neigh_key {
struct neighbour *n;
};
@@ -2186,9 +2283,6 @@ mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
return 0;
}
-static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
- struct mlxsw_sp_fib_entry *fib_entry);
-
static bool
mlxsw_sp_fib_node_entry_is_first(const struct mlxsw_sp_fib_node *fib_node,
const struct mlxsw_sp_fib_entry *fib_entry);
@@ -2779,6 +2873,8 @@ mlxsw_sp_fib_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry)
return !!nh_group->adj_index_valid;
case MLXSW_SP_FIB_ENTRY_TYPE_LOCAL:
return !!nh_group->nh_rif;
+ case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP:
+ return true;
default:
return false;
}
@@ -2810,7 +2906,8 @@ mlxsw_sp_fib4_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry)
struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group;
int i;
- if (fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL) {
+ if (fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL ||
+ fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP) {
nh_grp->nexthops->key.fib_nh->nh_flags |= RTNH_F_OFFLOAD;
return;
}
@@ -3015,6 +3112,22 @@ static int mlxsw_sp_fib_entry_op_trap(struct mlxsw_sp *mlxsw_sp,
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
}
+static int
+mlxsw_sp_fib_entry_op_ipip_decap(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_fib_entry *fib_entry,
+ enum mlxsw_reg_ralue_op op)
+{
+ struct mlxsw_sp_ipip_entry *ipip_entry = fib_entry->decap.ipip_entry;
+ const struct mlxsw_sp_ipip_ops *ipip_ops;
+
+ if (WARN_ON(!ipip_entry))
+ return -EINVAL;
+
+ ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt];
+ return ipip_ops->fib_entry_op(mlxsw_sp, ipip_entry, op,
+ fib_entry->decap.tunnel_index);
+}
+
static int __mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry,
enum mlxsw_reg_ralue_op op)
@@ -3026,6 +3139,9 @@ static int __mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
return mlxsw_sp_fib_entry_op_local(mlxsw_sp, fib_entry, op);
case MLXSW_SP_FIB_ENTRY_TYPE_TRAP:
return mlxsw_sp_fib_entry_op_trap(mlxsw_sp, fib_entry, op);
+ case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP:
+ return mlxsw_sp_fib_entry_op_ipip_decap(mlxsw_sp,
+ fib_entry, op);
}
return -EINVAL;
}
@@ -3060,11 +3176,23 @@ mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
const struct fib_entry_notifier_info *fen_info,
struct mlxsw_sp_fib_entry *fib_entry)
{
+ union mlxsw_sp_l3addr dip = { .addr4 = htonl(fen_info->dst) };
+ struct net_device *dev = fen_info->fi->fib_dev;
+ struct mlxsw_sp_ipip_entry *ipip_entry;
struct fib_info *fi = fen_info->fi;
switch (fen_info->type) {
- case RTN_BROADCAST: /* fall through */
case RTN_LOCAL:
+ ipip_entry = mlxsw_sp_ipip_entry_find_by_decap(mlxsw_sp, dev,
+ MLXSW_SP_L3_PROTO_IPV4, dip);
+ if (ipip_entry) {
+ fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP;
+ return mlxsw_sp_fib_entry_decap_init(mlxsw_sp,
+ fib_entry,
+ ipip_entry);
+ }
+ /* fall through */
+ case RTN_BROADCAST:
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
return 0;
case RTN_UNREACHABLE: /* fall through */
@@ -3557,6 +3685,9 @@ mlxsw_sp_fib4_node_entry_unlink(struct mlxsw_sp *mlxsw_sp,
{
mlxsw_sp_fib_node_entry_del(mlxsw_sp, &fib4_entry->common);
mlxsw_sp_fib4_node_list_remove(fib4_entry);
+
+ if (fib4_entry->common.type == MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP)
+ mlxsw_sp_fib_entry_decap_fini(mlxsw_sp, &fib4_entry->common);
}
static void mlxsw_sp_fib4_entry_replace(struct mlxsw_sp *mlxsw_sp,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index a5732aa..4276f5f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -97,5 +97,8 @@ mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
bool adding);
bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry);
+union mlxsw_sp_l3addr
+mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
+ const struct net_device *ol_dev);
#endif /* _MLXSW_ROUTER_H_*/
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 16/21] mlxsw: spectrum_router: Support IPv6 overlay encap
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
Add the missing bits to recognize IPv6 next hops as IPIP ones to enable
offloading of IPv6 overlay encapsulation.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 231b597..05afd53 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -3757,15 +3757,32 @@ mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry,
return NULL;
}
+static bool mlxsw_sp_nexthop6_ipip_type(const struct mlxsw_sp *mlxsw_sp,
+ const struct rt6_info *rt,
+ enum mlxsw_sp_ipip_type *ret)
+{
+ return rt->dst.dev &&
+ mlxsw_sp_netdev_ipip_type(mlxsw_sp, rt->dst.dev, ret);
+}
+
static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop *nh,
const struct rt6_info *rt)
{
+ struct mlxsw_sp_router *router = mlxsw_sp->router;
struct net_device *dev = rt->dst.dev;
+ enum mlxsw_sp_ipip_type ipipt;
struct mlxsw_sp_rif *rif;
int err;
+ if (mlxsw_sp_nexthop6_ipip_type(mlxsw_sp, rt, &ipipt) &&
+ router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev,
+ MLXSW_SP_L3_PROTO_IPV6)) {
+ nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
+ return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev);
+ }
+
nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
if (!rif)
@@ -3815,7 +3832,8 @@ static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,
static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp,
const struct rt6_info *rt)
{
- return rt->rt6i_flags & RTF_GATEWAY;
+ return rt->rt6i_flags & RTF_GATEWAY ||
+ mlxsw_sp_nexthop6_ipip_type(mlxsw_sp, rt, NULL);
}
static struct mlxsw_sp_nexthop_group *
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 15/21] mlxsw: spectrum_router: Support IPv4 overlay encap
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
This introduces some common code for tracking of offloaded IP-in-IP
tunnels, and support for offloading IPv4 overlay encapsulating routes in
particular. A follow-up patch will introduce IPv6 overlay as well.
Offloaded tunnels are kept in a linked list of mlxsw_sp_ipip_entry
objects hooked up in mlxsw_sp_router. A network device that represents
the tunnel is used as a key to look up the corresponding IPIP entry.
Note that in the future, more general keying mechanism will be needed,
because parts of the tunnel information can be provided by the route.
IPIP entries are reference counted, because several next hops may end up
using the same tunnel, and we only want to offload it once.
Encapsulation path hooks into next hop handling. Routes that forward to
a tunnel are now considered gateway routes, thus giving them the same
treatment that other remote routes get. An IPIP next hop type is
introduced.
Details of individual tunnel types are kept in an array of
mlxsw_sp_ipip_ops objects. If a tunnel type doesn't match any of the
known tunnel types, the next-hop is not considered an IPIP next hop.
The list of IPIP tunnel types is currently empty, follow-up patches will
add support for GRE. Traffic to IPIP tunnel types that are not
explicitly recognized by the driver traps and is handled in slow path.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 20 ++
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 238 ++++++++++++++++++++-
2 files changed, 257 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
index 65eb493..7b40aa2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
@@ -41,9 +41,29 @@ enum mlxsw_sp_ipip_type {
MLXSW_SP_IPIP_TYPE_MAX,
};
+struct mlxsw_sp_ipip_entry {
+ enum mlxsw_sp_ipip_type ipipt;
+ struct net_device *ol_dev; /* Overlay. */
+ struct mlxsw_sp_rif_ipip_lb *ol_lb;
+ unsigned int ref_count; /* Number of next hops using the tunnel. */
+ struct list_head ipip_list_node;
+};
+
struct mlxsw_sp_ipip_ops {
int dev_type;
enum mlxsw_sp_l3proto ul_proto; /* Underlay. */
+
+ int (*nexthop_update)(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
+ struct mlxsw_sp_ipip_entry *ipip_entry);
+
+ bool (*can_offload)(const struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *ol_dev,
+ enum mlxsw_sp_l3proto ol_proto);
+
+ /* Return a configuration for creating an overlay loopback RIF. */
+ struct mlxsw_sp_rif_ipip_lb_config
+ (*ol_loopback_config)(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *ol_dev);
};
extern const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[];
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 53bdd0f..231b597 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -89,6 +89,7 @@ struct mlxsw_sp_router {
struct delayed_work nexthop_probe_dw;
#define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */
struct list_head nexthop_neighs_list;
+ struct list_head ipip_list;
bool aborted;
struct notifier_block fib_nb;
const struct mlxsw_sp_rif_ops **rif_ops_arr;
@@ -915,6 +916,170 @@ static u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev)
return l3mdev_fib_table(ol_dev) ? : RT_TABLE_MAIN;
}
+static struct mlxsw_sp_rif *
+mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_rif_params *params);
+
+static struct mlxsw_sp_rif_ipip_lb *
+mlxsw_sp_ipip_ol_ipip_lb_create(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_ipip_type ipipt,
+ struct net_device *ol_dev)
+{
+ struct mlxsw_sp_rif_params_ipip_lb lb_params;
+ const struct mlxsw_sp_ipip_ops *ipip_ops;
+ struct mlxsw_sp_rif *rif;
+
+ ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt];
+ lb_params = (struct mlxsw_sp_rif_params_ipip_lb) {
+ .common.dev = ol_dev,
+ .common.lag = false,
+ .lb_config = ipip_ops->ol_loopback_config(mlxsw_sp, ol_dev),
+ };
+
+ rif = mlxsw_sp_rif_create(mlxsw_sp, &lb_params.common);
+ if (IS_ERR(rif))
+ return ERR_CAST(rif);
+ return container_of(rif, struct mlxsw_sp_rif_ipip_lb, common);
+}
+
+static struct mlxsw_sp_ipip_entry *
+mlxsw_sp_ipip_entry_alloc(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_ipip_type ipipt,
+ struct net_device *ol_dev)
+{
+ struct mlxsw_sp_ipip_entry *ipip_entry;
+ struct mlxsw_sp_ipip_entry *ret = NULL;
+
+ ipip_entry = kzalloc(sizeof(*ipip_entry), GFP_KERNEL);
+ if (!ipip_entry)
+ return ERR_PTR(-ENOMEM);
+
+ ipip_entry->ol_lb = mlxsw_sp_ipip_ol_ipip_lb_create(mlxsw_sp, ipipt,
+ ol_dev);
+ if (IS_ERR(ipip_entry->ol_lb)) {
+ ret = ERR_CAST(ipip_entry->ol_lb);
+ goto err_ol_ipip_lb_create;
+ }
+
+ ipip_entry->ipipt = ipipt;
+ ipip_entry->ol_dev = ol_dev;
+
+ return ipip_entry;
+
+err_ol_ipip_lb_create:
+ kfree(ipip_entry);
+ return ret;
+}
+
+static void
+mlxsw_sp_ipip_entry_destroy(struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ WARN_ON(ipip_entry->ref_count > 0);
+ mlxsw_sp_rif_destroy(&ipip_entry->ol_lb->common);
+ kfree(ipip_entry);
+}
+
+static __be32
+mlxsw_sp_ipip_netdev_saddr4(const struct net_device *ol_dev)
+{
+ struct ip_tunnel *tun = netdev_priv(ol_dev);
+
+ return tun->parms.iph.saddr;
+}
+
+union mlxsw_sp_l3addr
+mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
+ const struct net_device *ol_dev)
+{
+ switch (proto) {
+ case MLXSW_SP_L3_PROTO_IPV4:
+ return (union mlxsw_sp_l3addr) {
+ .addr4 = mlxsw_sp_ipip_netdev_saddr4(ol_dev),
+ };
+ case MLXSW_SP_L3_PROTO_IPV6:
+ break;
+ };
+
+ WARN_ON(1);
+ return (union mlxsw_sp_l3addr) {
+ .addr4 = 0,
+ };
+}
+
+static bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1,
+ const union mlxsw_sp_l3addr *addr2)
+{
+ return !memcmp(addr1, addr2, sizeof(*addr1));
+}
+
+static bool
+mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp,
+ const enum mlxsw_sp_l3proto ul_proto,
+ union mlxsw_sp_l3addr saddr,
+ u32 ul_tb_id,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ u32 tun_ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev);
+ enum mlxsw_sp_ipip_type ipipt = ipip_entry->ipipt;
+ union mlxsw_sp_l3addr tun_saddr;
+
+ if (mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto != ul_proto)
+ return false;
+
+ tun_saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ipip_entry->ol_dev);
+ return tun_ul_tb_id == ul_tb_id &&
+ mlxsw_sp_l3addr_eq(&tun_saddr, &saddr);
+}
+
+static struct mlxsw_sp_ipip_entry *
+mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_ipip_type ipipt,
+ struct net_device *ol_dev)
+{
+ u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ol_dev);
+ struct mlxsw_sp_router *router = mlxsw_sp->router;
+ struct mlxsw_sp_ipip_entry *ipip_entry;
+ enum mlxsw_sp_l3proto ul_proto;
+ union mlxsw_sp_l3addr saddr;
+
+ list_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list,
+ ipip_list_node) {
+ if (ipip_entry->ol_dev == ol_dev)
+ goto inc_ref_count;
+
+ /* The configuration where several tunnels have the same local
+ * address in the same underlay table needs special treatment in
+ * the HW. That is currently not implemented in the driver.
+ */
+ ul_proto = router->ipip_ops_arr[ipip_entry->ipipt]->ul_proto;
+ saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ol_dev);
+ if (mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, saddr,
+ ul_tb_id, ipip_entry))
+ return ERR_PTR(-EEXIST);
+ }
+
+ ipip_entry = mlxsw_sp_ipip_entry_alloc(mlxsw_sp, ipipt, ol_dev);
+ if (IS_ERR(ipip_entry))
+ return ipip_entry;
+
+ list_add_tail(&ipip_entry->ipip_list_node,
+ &mlxsw_sp->router->ipip_list);
+
+inc_ref_count:
+ ++ipip_entry->ref_count;
+ return ipip_entry;
+}
+
+static void
+mlxsw_sp_ipip_entry_put(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_ipip_entry *ipip_entry)
+{
+ if (--ipip_entry->ref_count == 0) {
+ list_del(&ipip_entry->ipip_list_node);
+ mlxsw_sp_ipip_entry_destroy(ipip_entry);
+ }
+}
+
struct mlxsw_sp_neigh_key {
struct neighbour *n;
};
@@ -1654,6 +1819,7 @@ static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_nexthop_type {
MLXSW_SP_NEXTHOP_TYPE_ETH,
+ MLXSW_SP_NEXTHOP_TYPE_IPIP,
};
struct mlxsw_sp_nexthop_key {
@@ -1683,6 +1849,7 @@ struct mlxsw_sp_nexthop {
enum mlxsw_sp_nexthop_type type;
union {
struct mlxsw_sp_neigh_entry *neigh_entry;
+ struct mlxsw_sp_ipip_entry *ipip_entry;
};
};
@@ -1970,6 +2137,16 @@ static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
}
+static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
+ u32 adj_index,
+ struct mlxsw_sp_nexthop *nh)
+{
+ const struct mlxsw_sp_ipip_ops *ipip_ops;
+
+ ipip_ops = mlxsw_sp->router->ipip_ops_arr[nh->ipip_entry->ipipt];
+ return ipip_ops->nexthop_update(mlxsw_sp, adj_index, nh->ipip_entry);
+}
+
static int
mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
@@ -1994,6 +2171,10 @@ mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
err = mlxsw_sp_nexthop_mac_update
(mlxsw_sp, adj_index, nh);
break;
+ case MLXSW_SP_NEXTHOP_TYPE_IPIP:
+ err = mlxsw_sp_nexthop_ipip_update
+ (mlxsw_sp, adj_index, nh);
+ break;
}
if (err)
return err;
@@ -2297,6 +2478,46 @@ static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,
return false;
}
+static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_ipip_type ipipt,
+ struct mlxsw_sp_nexthop *nh,
+ struct net_device *ol_dev)
+{
+ if (!nh->nh_grp->gateway || nh->ipip_entry)
+ return 0;
+
+ nh->ipip_entry = mlxsw_sp_ipip_entry_get(mlxsw_sp, ipipt, ol_dev);
+ if (IS_ERR(nh->ipip_entry))
+ return PTR_ERR(nh->ipip_entry);
+
+ __mlxsw_sp_nexthop_neigh_update(nh, false);
+ return 0;
+}
+
+static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop *nh)
+{
+ struct mlxsw_sp_ipip_entry *ipip_entry = nh->ipip_entry;
+
+ if (!ipip_entry)
+ return;
+
+ __mlxsw_sp_nexthop_neigh_update(nh, true);
+ mlxsw_sp_ipip_entry_put(mlxsw_sp, ipip_entry);
+ nh->ipip_entry = NULL;
+}
+
+static bool mlxsw_sp_nexthop4_ipip_type(const struct mlxsw_sp *mlxsw_sp,
+ const struct fib_nh *fib_nh,
+ enum mlxsw_sp_ipip_type *p_ipipt)
+{
+ struct net_device *dev = fib_nh->nh_dev;
+
+ return dev &&
+ fib_nh->nh_parent->fib_type == RTN_UNICAST &&
+ mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, p_ipipt);
+}
+
static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{
@@ -2305,6 +2526,9 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
mlxsw_sp_nexthop_rif_fini(nh);
break;
+ case MLXSW_SP_NEXTHOP_TYPE_IPIP:
+ mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh);
+ break;
}
}
@@ -2312,10 +2536,19 @@ static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh,
struct fib_nh *fib_nh)
{
+ struct mlxsw_sp_router *router = mlxsw_sp->router;
struct net_device *dev = fib_nh->nh_dev;
+ enum mlxsw_sp_ipip_type ipipt;
struct mlxsw_sp_rif *rif;
int err;
+ if (mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, fib_nh, &ipipt) &&
+ router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev,
+ MLXSW_SP_L3_PROTO_IPV4)) {
+ nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
+ return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev);
+ }
+
nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
if (!rif)
@@ -2421,7 +2654,8 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp,
const struct fib_info *fi)
{
- return fi->fib_nh->nh_scope == RT_SCOPE_LINK;
+ return fi->fib_nh->nh_scope == RT_SCOPE_LINK ||
+ mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, fi->fib_nh, NULL);
}
static struct mlxsw_sp_nexthop_group *
@@ -5411,11 +5645,13 @@ static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)
static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp)
{
mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr;
+ INIT_LIST_HEAD(&mlxsw_sp->router->ipip_list);
return 0;
}
static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp)
{
+ WARN_ON(!list_empty(&mlxsw_sp->router->ipip_list));
}
static void mlxsw_sp_router_fib_dump_flush(struct notifier_block *nb)
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 14/21] mlxsw: spectrum_router: Make nexthops typed
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
In the router, some next hops may reference an encapsulating netdevice,
such as GRE or IPIP. To properly offload these next hops, mlxsw needs to
keep track of whether a given next hop is a regular Ethernet entry, or
an IP-in-IP tunneling entry.
To facilitate this book-keeping, add a type field to struct
mlxsw_sp_nexthop. There is, as of this patch, only one next hop type:
MLXSW_SP_NEXTHOP_TYPE_ETH. Follow-up patches will introduce the IP-in-IP
variant.
There are several places where next hops are initialized in the IPv4
path. Instead of replicating the logic at every one of them, factor it
out to a function mlxsw_sp_nexthop4_type_init(). The corresponding fini
is actually protocol-neutral, so put it to mlxsw_sp_nexthop_type_fini(),
but create a corresponding protocoled _fini function that dispatches to
the protocol-neutral one.
The IPv6 path is simpler, but for symmetry with IPv4, create the same
suite of functions with corresponding logic.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 138 ++++++++++++++-------
1 file changed, 95 insertions(+), 43 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 563e803..53bdd0f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1652,6 +1652,10 @@ static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
}
}
+enum mlxsw_sp_nexthop_type {
+ MLXSW_SP_NEXTHOP_TYPE_ETH,
+};
+
struct mlxsw_sp_nexthop_key {
struct fib_nh *fib_nh;
};
@@ -1676,7 +1680,10 @@ struct mlxsw_sp_nexthop {
update:1; /* set indicates that MAC of this neigh should be
* updated in HW
*/
- struct mlxsw_sp_neigh_entry *neigh_entry;
+ enum mlxsw_sp_nexthop_type type;
+ union {
+ struct mlxsw_sp_neigh_entry *neigh_entry;
+ };
};
struct mlxsw_sp_nexthop_group {
@@ -1964,9 +1971,9 @@ static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
}
static int
-mlxsw_sp_nexthop_group_mac_update(struct mlxsw_sp *mlxsw_sp,
- struct mlxsw_sp_nexthop_group *nh_grp,
- bool reallocate)
+mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop_group *nh_grp,
+ bool reallocate)
{
u32 adj_index = nh_grp->adj_index; /* base */
struct mlxsw_sp_nexthop *nh;
@@ -1982,8 +1989,12 @@ mlxsw_sp_nexthop_group_mac_update(struct mlxsw_sp *mlxsw_sp,
}
if (nh->update || reallocate) {
- err = mlxsw_sp_nexthop_mac_update(mlxsw_sp,
- adj_index, nh);
+ switch (nh->type) {
+ case MLXSW_SP_NEXTHOP_TYPE_ETH:
+ err = mlxsw_sp_nexthop_mac_update
+ (mlxsw_sp, adj_index, nh);
+ break;
+ }
if (err)
return err;
nh->update = 0;
@@ -2071,8 +2082,7 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
/* Nothing was added or removed, so no need to reallocate. Just
* update MAC on existing adjacency indexes.
*/
- err = mlxsw_sp_nexthop_group_mac_update(mlxsw_sp, nh_grp,
- false);
+ err = mlxsw_sp_nexthop_group_update(mlxsw_sp, nh_grp, false);
if (err) {
dev_warn(mlxsw_sp->bus_info->dev, "Failed to update neigh MAC in adjacency table.\n");
goto set_trap;
@@ -2099,7 +2109,7 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
nh_grp->adj_index_valid = 1;
nh_grp->adj_index = adj_index;
nh_grp->ecmp_size = ecmp_size;
- err = mlxsw_sp_nexthop_group_mac_update(mlxsw_sp, nh_grp, true);
+ err = mlxsw_sp_nexthop_group_update(mlxsw_sp, nh_grp, true);
if (err) {
dev_warn(mlxsw_sp->bus_info->dev, "Failed to update neigh MAC in adjacency table.\n");
goto set_trap;
@@ -2287,6 +2297,48 @@ static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,
return false;
}
+static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop *nh)
+{
+ switch (nh->type) {
+ case MLXSW_SP_NEXTHOP_TYPE_ETH:
+ mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
+ mlxsw_sp_nexthop_rif_fini(nh);
+ break;
+ }
+}
+
+static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop *nh,
+ struct fib_nh *fib_nh)
+{
+ struct net_device *dev = fib_nh->nh_dev;
+ struct mlxsw_sp_rif *rif;
+ int err;
+
+ nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
+ rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
+ if (!rif)
+ return 0;
+
+ mlxsw_sp_nexthop_rif_init(nh, rif);
+ err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
+ if (err)
+ goto err_neigh_init;
+
+ return 0;
+
+err_neigh_init:
+ mlxsw_sp_nexthop_rif_fini(nh);
+ return err;
+}
+
+static void mlxsw_sp_nexthop4_type_fini(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop *nh)
+{
+ mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
+}
+
static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop *nh,
@@ -2294,7 +2346,6 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
{
struct net_device *dev = fib_nh->nh_dev;
struct in_device *in_dev;
- struct mlxsw_sp_rif *rif;
int err;
nh->nh_grp = nh_grp;
@@ -2312,19 +2363,13 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
fib_nh->nh_flags & RTNH_F_LINKDOWN)
return 0;
- rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
- if (!rif)
- return 0;
- mlxsw_sp_nexthop_rif_init(nh, rif);
-
- err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
+ err = mlxsw_sp_nexthop4_type_init(mlxsw_sp, nh, fib_nh);
if (err)
goto err_nexthop_neigh_init;
return 0;
err_nexthop_neigh_init:
- mlxsw_sp_nexthop_rif_fini(nh);
mlxsw_sp_nexthop_remove(mlxsw_sp, nh);
return err;
}
@@ -2332,8 +2377,7 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
static void mlxsw_sp_nexthop4_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{
- mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
- mlxsw_sp_nexthop_rif_fini(nh);
+ mlxsw_sp_nexthop4_type_fini(mlxsw_sp, nh);
mlxsw_sp_nexthop_remove(mlxsw_sp, nh);
}
@@ -2342,7 +2386,6 @@ static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp,
{
struct mlxsw_sp_nexthop_key key;
struct mlxsw_sp_nexthop *nh;
- struct mlxsw_sp_rif *rif;
if (mlxsw_sp->router->aborted)
return;
@@ -2352,18 +2395,12 @@ static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp,
if (WARN_ON_ONCE(!nh))
return;
- rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, fib_nh->nh_dev);
- if (!rif)
- return;
-
switch (event) {
case FIB_EVENT_NH_ADD:
- mlxsw_sp_nexthop_rif_init(nh, rif);
- mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
+ mlxsw_sp_nexthop4_type_init(mlxsw_sp, nh, fib_nh);
break;
case FIB_EVENT_NH_DEL:
- mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
- mlxsw_sp_nexthop_rif_fini(nh);
+ mlxsw_sp_nexthop4_type_fini(mlxsw_sp, nh);
break;
}
@@ -2376,8 +2413,7 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh, *tmp;
list_for_each_entry_safe(nh, tmp, &rif->nexthop_list, rif_list_node) {
- mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
- mlxsw_sp_nexthop_rif_fini(nh);
+ mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
}
}
@@ -3487,22 +3523,16 @@ mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry,
return NULL;
}
-static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
- struct mlxsw_sp_nexthop_group *nh_grp,
- struct mlxsw_sp_nexthop *nh,
- const struct rt6_info *rt)
+static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop_group *nh_grp,
+ struct mlxsw_sp_nexthop *nh,
+ const struct rt6_info *rt)
{
struct net_device *dev = rt->dst.dev;
struct mlxsw_sp_rif *rif;
int err;
- nh->nh_grp = nh_grp;
- memcpy(&nh->gw_addr, &rt->rt6i_gateway, sizeof(nh->gw_addr));
-
- if (!dev)
- return 0;
- nh->ifindex = dev->ifindex;
-
+ nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
if (!rif)
return 0;
@@ -3519,11 +3549,33 @@ static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
return err;
}
+static void mlxsw_sp_nexthop6_type_fini(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop *nh)
+{
+ mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
+}
+
+static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_nexthop_group *nh_grp,
+ struct mlxsw_sp_nexthop *nh,
+ const struct rt6_info *rt)
+{
+ struct net_device *dev = rt->dst.dev;
+
+ nh->nh_grp = nh_grp;
+ memcpy(&nh->gw_addr, &rt->rt6i_gateway, sizeof(nh->gw_addr));
+
+ if (!dev)
+ return 0;
+ nh->ifindex = dev->ifindex;
+
+ return mlxsw_sp_nexthop6_type_init(mlxsw_sp, nh_grp, nh, rt);
+}
+
static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{
- mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
- mlxsw_sp_nexthop_rif_fini(nh);
+ mlxsw_sp_nexthop6_type_fini(mlxsw_sp, nh);
}
static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp,
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 13/21] mlxsw: spectrum_router: Extract mlxsw_sp_rt6_is_gateway()
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
IPv6 counterpart of the previous patch: introduce a function to
determine whether a given route is a gateway route.
The new function takes a mlxsw_sp argument which follow-up patches will
use. Thus mlxsw_sp_fib6_entry_type_set() got that argument as well.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 04e1887..563e803 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -3526,6 +3526,12 @@ static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_nexthop_rif_fini(nh);
}
+static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp,
+ const struct rt6_info *rt)
+{
+ return rt->rt6i_flags & RTF_GATEWAY;
+}
+
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib6_entry *fib6_entry)
@@ -3548,7 +3554,7 @@ mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp,
#endif
mlxsw_sp_rt6 = list_first_entry(&fib6_entry->rt6_list,
struct mlxsw_sp_rt6, list);
- nh_grp->gateway = !!(mlxsw_sp_rt6->rt->rt6i_flags & RTF_GATEWAY);
+ nh_grp->gateway = mlxsw_sp_rt6_is_gateway(mlxsw_sp, mlxsw_sp_rt6->rt);
nh_grp->count = fib6_entry->nrt6;
for (i = 0; i < nh_grp->count; i++) {
struct rt6_info *rt = mlxsw_sp_rt6->rt;
@@ -3705,7 +3711,8 @@ mlxsw_sp_fib6_entry_nexthop_del(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
}
-static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp_fib_entry *fib_entry,
+static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_fib_entry *fib_entry,
const struct rt6_info *rt)
{
/* Packets hitting RTF_REJECT routes need to be discarded by the
@@ -3718,7 +3725,7 @@ static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp_fib_entry *fib_entry,
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
else if (rt->rt6i_flags & RTF_REJECT)
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
- else if (rt->rt6i_flags & RTF_GATEWAY)
+ else if (mlxsw_sp_rt6_is_gateway(mlxsw_sp, rt))
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
else
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
@@ -3758,7 +3765,7 @@ mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp,
goto err_rt6_create;
}
- mlxsw_sp_fib6_entry_type_set(fib_entry, mlxsw_sp_rt6->rt);
+ mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, mlxsw_sp_rt6->rt);
INIT_LIST_HEAD(&fib6_entry->rt6_list);
list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 12/21] mlxsw: spectrum_router: Extract mlxsw_sp_fi_is_gateway()
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
For IPv4 IP-in-IP offload, routes that direct traffic to IP-in-IP
devices need to be considered gateway routes as well. That involves a
bit more logic, so extract the current test to a separate function,
where the logic can be later added.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 72e386b..04e1887 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -2382,6 +2382,12 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
}
}
+static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp,
+ const struct fib_info *fi)
+{
+ return fi->fib_nh->nh_scope == RT_SCOPE_LINK;
+}
+
static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
{
@@ -2401,7 +2407,7 @@ mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
INIT_LIST_HEAD(&nh_grp->fib_list);
nh_grp->neigh_tbl = &arp_tbl;
- nh_grp->gateway = fi->fib_nh->nh_scope == RT_SCOPE_LINK;
+ nh_grp->gateway = mlxsw_sp_fi_is_gateway(mlxsw_sp, fi);
nh_grp->count = fi->fib_nhs;
fib_info_hold(fi);
for (i = 0; i < nh_grp->count; i++) {
@@ -2801,10 +2807,10 @@ mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
return 0;
case RTN_UNICAST:
- if (fi->fib_nh->nh_scope != RT_SCOPE_LINK)
- fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
- else
+ if (mlxsw_sp_fi_is_gateway(mlxsw_sp, fi))
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
+ else
+ fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
return 0;
default:
return -EINVAL;
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 11/21] mlxsw: spectrum_router: Introduce loopback RIFs
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
When offloading L3 tunnels, an adjacency entry is created that loops the
packet back into the underlay router. Loopback interfaces then hold the
corresponding information and are created for IP-in-IP netdevices.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 1 +
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 152 ++++++++++++++++++++-
.../net/ethernet/mellanox/mlxsw/spectrum_router.h | 13 ++
3 files changed, 164 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index f8c7f7e..84ce83a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -77,6 +77,7 @@ enum mlxsw_sp_rif_type {
MLXSW_SP_RIF_TYPE_SUBPORT,
MLXSW_SP_RIF_TYPE_VLAN,
MLXSW_SP_RIF_TYPE_FID,
+ MLXSW_SP_RIF_TYPE_IPIP_LB, /* IP-in-IP loopback. */
MLXSW_SP_RIF_TYPE_MAX,
};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 38477c5..72e386b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1,9 +1,10 @@
/*
* drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016-2017 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
* Copyright (c) 2016 Ido Schimmel <idosch@mellanox.com>
* Copyright (c) 2016 Yotam Gigi <yotamg@mellanox.com>
+ * Copyright (c) 2017 Petr Machata <petrm@mellanox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -51,6 +52,7 @@
#include <net/ip_fib.h>
#include <net/ip6_fib.h>
#include <net/fib_rules.h>
+#include <net/ip_tunnels.h>
#include <net/l3mdev.h>
#include <net/addrconf.h>
#include <net/ndisc.h>
@@ -131,6 +133,17 @@ struct mlxsw_sp_rif_subport {
bool lag;
};
+struct mlxsw_sp_rif_ipip_lb {
+ struct mlxsw_sp_rif common;
+ struct mlxsw_sp_rif_ipip_lb_config lb_config;
+ u16 ul_vr_id; /* Reserved for Spectrum-2. */
+};
+
+struct mlxsw_sp_rif_params_ipip_lb {
+ struct mlxsw_sp_rif_params common;
+ struct mlxsw_sp_rif_ipip_lb_config lb_config;
+};
+
struct mlxsw_sp_rif_ops {
enum mlxsw_sp_rif_type type;
size_t rif_size;
@@ -883,6 +896,25 @@ static void mlxsw_sp_vrs_fini(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->router->vrs);
}
+static struct net_device *
+__mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev)
+{
+ struct ip_tunnel *tun = netdev_priv(ol_dev);
+ struct net *net = dev_net(ol_dev);
+
+ return __dev_get_by_index(net, tun->parms.link);
+}
+
+static u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev)
+{
+ struct net_device *d = __mlxsw_sp_ipip_netdev_ul_dev_get(ol_dev);
+
+ if (d)
+ return l3mdev_fib_table(d) ? : RT_TABLE_MAIN;
+ else
+ return l3mdev_fib_table(ol_dev) ? : RT_TABLE_MAIN;
+}
+
struct mlxsw_sp_neigh_key {
struct neighbour *n;
};
@@ -2236,6 +2268,25 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
neigh_release(n);
}
+static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *dev,
+ enum mlxsw_sp_ipip_type *p_type)
+{
+ struct mlxsw_sp_router *router = mlxsw_sp->router;
+ const struct mlxsw_sp_ipip_ops *ipip_ops;
+ enum mlxsw_sp_ipip_type ipipt;
+
+ for (ipipt = 0; ipipt < MLXSW_SP_IPIP_TYPE_MAX; ++ipipt) {
+ ipip_ops = router->ipip_ops_arr[ipipt];
+ if (dev->type == ipip_ops->dev_type) {
+ if (p_type)
+ *p_type = ipipt;
+ return true;
+ }
+ }
+ return false;
+}
+
static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct mlxsw_sp_nexthop *nh,
@@ -4374,7 +4425,10 @@ mlxsw_sp_dev_rif_type(const struct mlxsw_sp *mlxsw_sp,
{
enum mlxsw_sp_fid_type type;
- /* RIF type is derived from the type of the underlying FID */
+ if (mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL))
+ return MLXSW_SP_RIF_TYPE_IPIP_LB;
+
+ /* Otherwise RIF type is derived from the type of the underlying FID. */
if (is_vlan_dev(dev) && netif_is_bridge_master(vlan_dev_real_dev(dev)))
type = MLXSW_SP_FID_TYPE_8021Q;
else if (netif_is_bridge_master(dev) && br_vlan_enabled(dev))
@@ -5164,10 +5218,104 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = {
.fid_get = mlxsw_sp_rif_fid_fid_get,
};
+static struct mlxsw_sp_rif_ipip_lb *
+mlxsw_sp_rif_ipip_lb_rif(struct mlxsw_sp_rif *rif)
+{
+ return container_of(rif, struct mlxsw_sp_rif_ipip_lb, common);
+}
+
+static void
+mlxsw_sp_rif_ipip_lb_setup(struct mlxsw_sp_rif *rif,
+ const struct mlxsw_sp_rif_params *params)
+{
+ struct mlxsw_sp_rif_params_ipip_lb *params_lb;
+ struct mlxsw_sp_rif_ipip_lb *rif_lb;
+
+ params_lb = container_of(params, struct mlxsw_sp_rif_params_ipip_lb,
+ common);
+ rif_lb = mlxsw_sp_rif_ipip_lb_rif(rif);
+ rif_lb->lb_config = params_lb->lb_config;
+}
+
+static int
+mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif,
+ struct mlxsw_sp_vr *ul_vr, bool enable)
+{
+ struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
+ struct mlxsw_sp_rif *rif = &lb_rif->common;
+ struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
+ char ritr_pl[MLXSW_REG_RITR_LEN];
+ u32 saddr4;
+
+ switch (lb_cf.ul_protocol) {
+ case MLXSW_SP_L3_PROTO_IPV4:
+ saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
+ mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
+ rif->rif_index, rif->vr_id, rif->dev->mtu);
+ mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
+ MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
+ ul_vr->id, saddr4, lb_cf.okey);
+ break;
+
+ case MLXSW_SP_L3_PROTO_IPV6:
+ return -EAFNOSUPPORT;
+ }
+
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
+}
+
+static int
+mlxsw_sp_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
+{
+ struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif);
+ u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(rif->dev);
+ struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
+ struct mlxsw_sp_vr *ul_vr;
+ int err;
+
+ ul_vr = mlxsw_sp_vr_get(mlxsw_sp, ul_tb_id);
+ if (IS_ERR(ul_vr))
+ return PTR_ERR(ul_vr);
+
+ err = mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr, true);
+ if (err)
+ goto err_loopback_op;
+
+ lb_rif->ul_vr_id = ul_vr->id;
+ ++ul_vr->rif_count;
+ return 0;
+
+err_loopback_op:
+ mlxsw_sp_vr_put(ul_vr);
+ return err;
+}
+
+static void mlxsw_sp_rif_ipip_lb_deconfigure(struct mlxsw_sp_rif *rif)
+{
+ struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif);
+ struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
+ struct mlxsw_sp_vr *ul_vr;
+
+ ul_vr = &mlxsw_sp->router->vrs[lb_rif->ul_vr_id];
+ mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr, false);
+
+ --ul_vr->rif_count;
+ mlxsw_sp_vr_put(ul_vr);
+}
+
+static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_ipip_lb_ops = {
+ .type = MLXSW_SP_RIF_TYPE_IPIP_LB,
+ .rif_size = sizeof(struct mlxsw_sp_rif_ipip_lb),
+ .setup = mlxsw_sp_rif_ipip_lb_setup,
+ .configure = mlxsw_sp_rif_ipip_lb_configure,
+ .deconfigure = mlxsw_sp_rif_ipip_lb_deconfigure,
+};
+
static const struct mlxsw_sp_rif_ops *mlxsw_sp_rif_ops_arr[] = {
[MLXSW_SP_RIF_TYPE_SUBPORT] = &mlxsw_sp_rif_subport_ops,
[MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp_rif_vlan_ops,
[MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops,
+ [MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp_rif_ipip_lb_ops,
};
static int mlxsw_sp_rifs_init(struct mlxsw_sp *mlxsw_sp)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index 67c6c1d..a5732aa 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -36,12 +36,25 @@
#define _MLXSW_ROUTER_H_
#include "spectrum.h"
+#include "reg.h"
enum mlxsw_sp_l3proto {
MLXSW_SP_L3_PROTO_IPV4,
MLXSW_SP_L3_PROTO_IPV6,
};
+union mlxsw_sp_l3addr {
+ __be32 addr4;
+ struct in6_addr addr6;
+};
+
+struct mlxsw_sp_rif_ipip_lb_config {
+ enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
+ u32 okey;
+ enum mlxsw_sp_l3proto ul_protocol; /* Underlay. */
+ union mlxsw_sp_l3addr saddr;
+};
+
enum mlxsw_sp_rif_counter_dir {
MLXSW_SP_RIF_COUNTER_INGRESS,
MLXSW_SP_RIF_COUNTER_EGRESS,
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 10/21] mlxsw: spectrum_router: Support FID-less RIFs
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
Loopback RIFs, which will be introduced in a follow-up patch, differ
from other RIFs in that they do not have a FID associated with them.
To support this, demote FID allocation from mlxsw_sp_rif_create to
configure op of the existing RIF types, and likewise the FID release
from mlxsw_sp_rif_destroy to deconfigure op.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 85 ++++++++++++++++------
1 file changed, 63 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index f85d249..38477c5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -4444,9 +4444,9 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
{
u32 tb_id = l3mdev_fib_table(params->dev);
const struct mlxsw_sp_rif_ops *ops;
+ struct mlxsw_sp_fid *fid = NULL;
enum mlxsw_sp_rif_type type;
struct mlxsw_sp_rif *rif;
- struct mlxsw_sp_fid *fid;
struct mlxsw_sp_vr *vr;
u16 rif_index;
int err;
@@ -4470,12 +4470,14 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
rif->mlxsw_sp = mlxsw_sp;
rif->ops = ops;
- fid = ops->fid_get(rif);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- goto err_fid_get;
+ if (ops->fid_get) {
+ fid = ops->fid_get(rif);
+ if (IS_ERR(fid)) {
+ err = PTR_ERR(fid);
+ goto err_fid_get;
+ }
+ rif->fid = fid;
}
- rif->fid = fid;
if (ops->setup)
ops->setup(rif, params);
@@ -4484,22 +4486,15 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
if (err)
goto err_configure;
- err = mlxsw_sp_rif_fdb_op(mlxsw_sp, params->dev->dev_addr,
- mlxsw_sp_fid_index(fid), true);
- if (err)
- goto err_rif_fdb_op;
-
mlxsw_sp_rif_counters_alloc(rif);
- mlxsw_sp_fid_rif_set(fid, rif);
mlxsw_sp->router->rifs[rif_index] = rif;
vr->rif_count++;
return rif;
-err_rif_fdb_op:
- ops->deconfigure(rif);
err_configure:
- mlxsw_sp_fid_put(fid);
+ if (fid)
+ mlxsw_sp_fid_put(fid);
err_fid_get:
kfree(rif);
err_rif_alloc:
@@ -4520,12 +4515,11 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
vr->rif_count--;
mlxsw_sp->router->rifs[rif->rif_index] = NULL;
- mlxsw_sp_fid_rif_set(fid, NULL);
mlxsw_sp_rif_counters_free(rif);
- mlxsw_sp_rif_fdb_op(mlxsw_sp, rif->dev->dev_addr,
- mlxsw_sp_fid_index(fid), false);
ops->deconfigure(rif);
- mlxsw_sp_fid_put(fid);
+ if (fid)
+ /* Loopback RIFs are not associated with a FID. */
+ mlxsw_sp_fid_put(fid);
kfree(rif);
mlxsw_sp_vr_put(vr);
}
@@ -4965,11 +4959,32 @@ static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable)
static int mlxsw_sp_rif_subport_configure(struct mlxsw_sp_rif *rif)
{
- return mlxsw_sp_rif_subport_op(rif, true);
+ int err;
+
+ err = mlxsw_sp_rif_subport_op(rif, true);
+ if (err)
+ return err;
+
+ err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
+ mlxsw_sp_fid_index(rif->fid), true);
+ if (err)
+ goto err_rif_fdb_op;
+
+ mlxsw_sp_fid_rif_set(rif->fid, rif);
+ return 0;
+
+err_rif_fdb_op:
+ mlxsw_sp_rif_subport_op(rif, false);
+ return err;
}
static void mlxsw_sp_rif_subport_deconfigure(struct mlxsw_sp_rif *rif)
{
+ struct mlxsw_sp_fid *fid = rif->fid;
+
+ mlxsw_sp_fid_rif_set(fid, NULL);
+ mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
+ mlxsw_sp_fid_index(fid), false);
mlxsw_sp_rif_subport_op(rif, false);
}
@@ -5028,8 +5043,17 @@ static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif)
if (err)
goto err_fid_bc_flood_set;
+ err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
+ mlxsw_sp_fid_index(rif->fid), true);
+ if (err)
+ goto err_rif_fdb_op;
+
+ mlxsw_sp_fid_rif_set(rif->fid, rif);
return 0;
+err_rif_fdb_op:
+ mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
+ mlxsw_sp_router_port(mlxsw_sp), false);
err_fid_bc_flood_set:
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
mlxsw_sp_router_port(mlxsw_sp), false);
@@ -5040,9 +5064,13 @@ static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif)
static void mlxsw_sp_rif_vlan_deconfigure(struct mlxsw_sp_rif *rif)
{
- struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
+ struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
+ struct mlxsw_sp_fid *fid = rif->fid;
+ mlxsw_sp_fid_rif_set(fid, NULL);
+ mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
+ mlxsw_sp_fid_index(fid), false);
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
mlxsw_sp_router_port(mlxsw_sp), false);
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
@@ -5087,8 +5115,17 @@ static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif)
if (err)
goto err_fid_bc_flood_set;
+ err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
+ mlxsw_sp_fid_index(rif->fid), true);
+ if (err)
+ goto err_rif_fdb_op;
+
+ mlxsw_sp_fid_rif_set(rif->fid, rif);
return 0;
+err_rif_fdb_op:
+ mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
+ mlxsw_sp_router_port(mlxsw_sp), false);
err_fid_bc_flood_set:
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
mlxsw_sp_router_port(mlxsw_sp), false);
@@ -5099,9 +5136,13 @@ static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif)
static void mlxsw_sp_rif_fid_deconfigure(struct mlxsw_sp_rif *rif)
{
- struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
u16 fid_index = mlxsw_sp_fid_index(rif->fid);
+ struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
+ struct mlxsw_sp_fid *fid = rif->fid;
+ mlxsw_sp_fid_rif_set(fid, NULL);
+ mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
+ mlxsw_sp_fid_index(fid), false);
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
mlxsw_sp_router_port(mlxsw_sp), false);
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 09/21] mlxsw: spectrum_router: Add mlxsw_sp_ipip_ops
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
Details of individual tunnel types are kept in an array of
mlxsw_sp_ipip_ops objects. Follow-up patches will use the list to
determine whether a constructed RIF should be a loopback, and to decide
whether a next hop references a tunnel.
The list is currently empty, follow-up patches will add support for GRE.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/Makefile | 4 +-
.../net/ethernet/mellanox/mlxsw/spectrum_ipip.c | 38 ++++++++++++++++
.../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 51 ++++++++++++++++++++++
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 19 ++++++++
4 files changed, 110 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Makefile b/drivers/net/ethernet/mellanox/mlxsw/Makefile
index f9956f3..891ff41 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Makefile
+++ b/drivers/net/ethernet/mellanox/mlxsw/Makefile
@@ -16,8 +16,8 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_switchdev.o spectrum_router.o \
spectrum_kvdl.o spectrum_acl_tcam.o \
spectrum_acl.o spectrum_flower.o \
- spectrum_cnt.o \
- spectrum_fid.o
+ spectrum_cnt.o spectrum_fid.o \
+ spectrum_ipip.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
new file mode 100644
index 0000000..20b0b96
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
@@ -0,0 +1,38 @@
+/*
+ * drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Petr Machata <petrm@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "spectrum_ipip.h"
+
+const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[] = {
+};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
new file mode 100644
index 0000000..65eb493
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
@@ -0,0 +1,51 @@
+/*
+ * drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Petr Machata <petrm@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MLXSW_IPIP_H_
+#define _MLXSW_IPIP_H_
+
+#include "spectrum_router.h"
+
+enum mlxsw_sp_ipip_type {
+ MLXSW_SP_IPIP_TYPE_MAX,
+};
+
+struct mlxsw_sp_ipip_ops {
+ int dev_type;
+ enum mlxsw_sp_l3proto ul_proto; /* Underlay. */
+};
+
+extern const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[];
+
+#endif /* _MLXSW_IPIP_H_*/
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index f866ac5..f85d249 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -62,6 +62,7 @@
#include "reg.h"
#include "spectrum_cnt.h"
#include "spectrum_dpipe.h"
+#include "spectrum_ipip.h"
#include "spectrum_router.h"
struct mlxsw_sp_vr;
@@ -89,6 +90,7 @@ struct mlxsw_sp_router {
bool aborted;
struct notifier_block fib_nb;
const struct mlxsw_sp_rif_ops **rif_ops_arr;
+ const struct mlxsw_sp_ipip_ops **ipip_ops_arr;
};
struct mlxsw_sp_rif {
@@ -5152,6 +5154,16 @@ static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->router->rifs);
}
+static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp)
+{
+ mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr;
+ return 0;
+}
+
+static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp)
+{
+}
+
static void mlxsw_sp_router_fib_dump_flush(struct notifier_block *nb)
{
struct mlxsw_sp_router *router;
@@ -5211,6 +5223,10 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
if (err)
goto err_rifs_init;
+ err = mlxsw_sp_ipips_init(mlxsw_sp);
+ if (err)
+ goto err_ipips_init;
+
err = rhashtable_init(&mlxsw_sp->router->nexthop_ht,
&mlxsw_sp_nexthop_ht_params);
if (err)
@@ -5252,6 +5268,8 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
err_nexthop_group_ht_init:
rhashtable_destroy(&mlxsw_sp->router->nexthop_ht);
err_nexthop_ht_init:
+ mlxsw_sp_ipips_fini(mlxsw_sp);
+err_ipips_init:
mlxsw_sp_rifs_fini(mlxsw_sp);
err_rifs_init:
__mlxsw_sp_router_fini(mlxsw_sp);
@@ -5268,6 +5286,7 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
mlxsw_sp_lpm_fini(mlxsw_sp);
rhashtable_destroy(&mlxsw_sp->router->nexthop_group_ht);
rhashtable_destroy(&mlxsw_sp->router->nexthop_ht);
+ mlxsw_sp_ipips_fini(mlxsw_sp);
mlxsw_sp_rifs_fini(mlxsw_sp);
__mlxsw_sp_router_fini(mlxsw_sp);
kfree(mlxsw_sp->router);
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 08/21] mlxsw: spectrum_router: Publish mlxsw_sp_l3proto
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
The spectrum_ipip module that will be introduced in the follow-up
patches needs to know the data type.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 5 -----
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h | 5 +++++
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 4e47d45..f866ac5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -405,11 +405,6 @@ struct mlxsw_sp_rt6 {
struct rt6_info *rt;
};
-enum mlxsw_sp_l3proto {
- MLXSW_SP_L3_PROTO_IPV4,
- MLXSW_SP_L3_PROTO_IPV6,
-};
-
struct mlxsw_sp_lpm_tree {
u8 id; /* tree ID */
unsigned int ref_count;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index 87a04af..67c6c1d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -37,6 +37,11 @@
#include "spectrum.h"
+enum mlxsw_sp_l3proto {
+ MLXSW_SP_L3_PROTO_IPV4,
+ MLXSW_SP_L3_PROTO_IPV6,
+};
+
enum mlxsw_sp_rif_counter_dir {
MLXSW_SP_RIF_COUNTER_INGRESS,
MLXSW_SP_RIF_COUNTER_EGRESS,
--
2.9.3
^ permalink raw reply related
* [patch net-next v2 07/21] mlxsw: reg: Give mlxsw_reg_ratr_pack a type parameter
From: Jiri Pirko @ 2017-09-02 21:49 UTC (permalink / raw)
To: netdev; +Cc: davem, petrm, idosch, mlxsw
In-Reply-To: <20170902214929.2890-1-jiri@resnulli.us>
From: Petr Machata <petrm@mellanox.com>
To support IPIP, the driver needs to be able to construct an IPIP
adjacency. Change mlxsw_reg_ratr_pack to take an adjacency type as an
argument. Adjust the one existing caller.
Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/reg.h | 2 ++
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index d80cf9b..cc27c5d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -4483,11 +4483,13 @@ MLXSW_ITEM32(reg, ratr, ipip_ipv6_ptr, 0x1C, 0, 24);
static inline void
mlxsw_reg_ratr_pack(char *payload,
enum mlxsw_reg_ratr_op op, bool valid,
+ enum mlxsw_reg_ratr_type type,
u32 adjacency_index, u16 egress_rif)
{
MLXSW_REG_ZERO(ratr, payload);
mlxsw_reg_ratr_op_set(payload, op);
mlxsw_reg_ratr_v_set(payload, valid);
+ mlxsw_reg_ratr_type_set(payload, type);
mlxsw_reg_ratr_adjacency_index_low_set(payload, adjacency_index);
mlxsw_reg_ratr_adjacency_index_high_set(payload, adjacency_index >> 16);
mlxsw_reg_ratr_egress_router_interface_set(payload, egress_rif);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 3ddfbe3..4e47d45 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1928,7 +1928,8 @@ static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
char ratr_pl[MLXSW_REG_RATR_LEN];
mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY,
- true, adj_index, neigh_entry->rif);
+ true, MLXSW_REG_RATR_TYPE_ETHERNET,
+ adj_index, neigh_entry->rif);
mlxsw_reg_ratr_eth_entry_pack(ratr_pl, neigh_entry->ha);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
}
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox