* [patch net-next 0/5] net: sched: let the offloader decide what to offload
From: Jiri Pirko @ 2017-08-09 12:30 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw, andrew, vivien.didelot,
f.fainelli, jakub.kicinski, simon.horman, pieter.jansenvanvuuren,
oss-drivers, ganeshgr, jeffrey.t.kirsher, saeedm, matanb, leonro
From: Jiri Pirko <jiri@mellanox.com>
Currently there is a Qdisc_class_ops->tcf_cl_offload callback
that is called to find out if cls would offload rule or not.
This is only supported by sch_ingress and sch_clsact.
So the Qdisc are to decide. However, the driver knows what is he
able to offload, so move the decision making to drivers completely.
Just pass classid there and provide set of helpers to allow
identification of qdisc.
As a side effect, this actually allows clsact egress rules
offload in mlxsw.
Jiri Pirko (5):
net: sched: Add helpers to identify classids
net: sched: propagate classid down to offload drivers
net: sched: use newly added classid identity helpers
net: sched: remove handle propagation down to the drivers
net: sched: remove cops->tcf_cl_offload
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 18 ++++++++++++++++--
drivers/net/ethernet/netronome/nfp/bpf/main.c | 2 +-
drivers/net/ethernet/netronome/nfp/flower/offload.c | 2 +-
include/net/pkt_cls.h | 18 +++++-------------
include/net/pkt_sched.h | 14 ++++++++++++++
include/net/sch_generic.h | 1 -
net/dsa/slave.c | 9 ++++++++-
net/sched/cls_bpf.c | 4 ++--
net/sched/cls_flower.c | 8 ++++----
net/sched/cls_matchall.c | 4 ++--
net/sched/cls_u32.c | 8 ++++----
net/sched/sch_ingress.c | 12 ------------
16 files changed, 61 insertions(+), 47 deletions(-)
--
2.9.3
^ permalink raw reply
* [patch net-next 1/5] net: sched: Add helpers to identify classids
From: Jiri Pirko @ 2017-08-09 12:30 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw, andrew, vivien.didelot,
f.fainelli, jakub.kicinski, simon.horman, pieter.jansenvanvuuren,
oss-drivers, ganeshgr, jeffrey.t.kirsher, saeedm, matanb, leonro
In-Reply-To: <20170809123035.7663-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Offloading drivers need to understand what qdisc class a filter is added
to. Currently they only need to identify ingress, clsact->ingress and
clsact->egress. So provide these helpers.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/net/pkt_sched.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 2579c20..259bc19 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -5,6 +5,7 @@
#include <linux/ktime.h>
#include <linux/if_vlan.h>
#include <net/sch_generic.h>
+#include <uapi/linux/pkt_sched.h>
#define DEFAULT_TX_QUEUE_LEN 1000
@@ -132,4 +133,17 @@ static inline unsigned int psched_mtu(const struct net_device *dev)
return dev->mtu + dev->hard_header_len;
}
+static inline bool is_classid_clsact_ingress(u32 classid)
+{
+ /* This also returns true for ingress qdisc */
+ return TC_H_MAJ(classid) == TC_H_MAJ(TC_H_CLSACT) &&
+ TC_H_MIN(classid) != TC_H_MIN(TC_H_MIN_EGRESS);
+}
+
+static inline bool is_classid_clsact_egress(u32 classid)
+{
+ return TC_H_MAJ(classid) == TC_H_MAJ(TC_H_CLSACT) &&
+ TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_EGRESS);
+}
+
#endif
--
2.9.3
^ permalink raw reply related
* [patch net-next 2/5] net: sched: propagate classid down to offload drivers
From: Jiri Pirko @ 2017-08-09 12:30 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw, andrew, vivien.didelot,
f.fainelli, jakub.kicinski, simon.horman, pieter.jansenvanvuuren,
oss-drivers, ganeshgr, jeffrey.t.kirsher, saeedm, matanb, leonro
In-Reply-To: <20170809123035.7663-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Drivers need classid to decide they support this specific qdisc+class
or not. So propagate it down via the tc_cls_common_offload struct.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/net/pkt_cls.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 0f78e65..1f1de20 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -410,6 +410,7 @@ struct tc_cls_common_offload {
u32 chain_index;
__be16 protocol;
u32 prio;
+ u32 classid;
};
static inline void
@@ -420,6 +421,7 @@ tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
cls_common->chain_index = tp->chain->index;
cls_common->protocol = tp->protocol;
cls_common->prio = tp->prio;
+ cls_common->classid = tp->classid;
}
struct tc_cls_u32_knode {
--
2.9.3
^ permalink raw reply related
* [patch net-next 3/5] net: sched: use newly added classid identity helpers
From: Jiri Pirko @ 2017-08-09 12:30 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw, andrew, vivien.didelot,
f.fainelli, jakub.kicinski, simon.horman, pieter.jansenvanvuuren,
oss-drivers, ganeshgr, jeffrey.t.kirsher, saeedm, matanb, leonro
In-Reply-To: <20170809123035.7663-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Instead of checking handle, which does not have the inner class
information and drivers wrongly assume clsact->egress as ingress, use
the newly introduced classid identification helpers.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 18 ++++++++++++++++--
drivers/net/ethernet/netronome/nfp/bpf/main.c | 2 +-
drivers/net/ethernet/netronome/nfp/flower/offload.c | 2 +-
net/dsa/slave.c | 9 ++++++++-
8 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index d80b20d..afa6fd6 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2892,7 +2892,7 @@ static int cxgb_set_tx_maxrate(struct net_device *dev, int index, u32 rate)
static int cxgb_setup_tc_cls_u32(struct net_device *dev,
struct tc_cls_u32_offload *cls_u32)
{
- if (TC_H_MAJ(cls_u32->common.handle) != TC_H_MAJ(TC_H_INGRESS) ||
+ if (is_classid_clsact_ingress(cls_u32->common.classid) ||
cls_u32->common.chain_index)
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index c6b1324..f9fd8d8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9230,7 +9230,7 @@ static int ixgbe_setup_tc_cls_u32(struct net_device *dev,
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
- if (TC_H_MAJ(cls_u32->common.handle) != TC_H_MAJ(TC_H_INGRESS) ||
+ if (is_classid_clsact_ingress(cls_u32->common.classid) ||
cls_u32->common.chain_index)
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 981f841..8633ca5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3031,7 +3031,7 @@ static int mlx5e_setup_tc_cls_flower(struct net_device *dev,
{
struct mlx5e_priv *priv = netdev_priv(dev);
- if (TC_H_MAJ(cls_flower->common.handle) != TC_H_MAJ(TC_H_INGRESS) ||
+ if (is_classid_clsact_ingress(cls_flower->common.classid) ||
cls_flower->common.chain_index)
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index f3c494a..f34c00f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -657,7 +657,7 @@ mlx5e_rep_setup_tc_cls_flower(struct net_device *dev,
{
struct mlx5e_priv *priv = netdev_priv(dev);
- if (TC_H_MAJ(cls_flower->common.handle) != TC_H_MAJ(TC_H_INGRESS) ||
+ if (is_classid_clsact_ingress(cls_flower->common.classid) ||
cls_flower->common.chain_index)
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index eb7c454..a996003 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1696,7 +1696,14 @@ static void mlxsw_sp_port_del_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
static int mlxsw_sp_setup_tc_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_cls_matchall_offload *f)
{
- bool ingress = TC_H_MAJ(f->common.handle) == TC_H_MAJ(TC_H_INGRESS);
+ bool ingress;
+
+ if (is_classid_clsact_ingress(f->common.classid))
+ ingress = true;
+ else if (is_classid_clsact_egress(f->common.classid))
+ ingress = false;
+ else
+ return -EOPNOTSUPP;
if (f->common.chain_index)
return -EOPNOTSUPP;
@@ -1717,7 +1724,14 @@ static int
mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_cls_flower_offload *f)
{
- bool ingress = TC_H_MAJ(f->common.handle) == TC_H_MAJ(TC_H_INGRESS);
+ bool ingress;
+
+ if (is_classid_clsact_ingress(f->common.classid))
+ ingress = true;
+ else if (is_classid_clsact_egress(f->common.classid))
+ ingress = false;
+ else
+ return -EOPNOTSUPP;
if (f->common.chain_index)
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index f981f60..0e68649 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -127,7 +127,7 @@ static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
struct nfp_net *nn = netdev_priv(netdev);
if (type != TC_SETUP_CLSBPF || !nfp_net_ebpf_capable(nn) ||
- TC_H_MAJ(cls_bpf->common.handle) != TC_H_MAJ(TC_H_INGRESS) ||
+ is_classid_clsact_ingress(cls_bpf->common.classid) ||
cls_bpf->common.protocol != htons(ETH_P_ALL) ||
cls_bpf->common.chain_index)
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index 01767c7..3ad5aaa 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -390,7 +390,7 @@ int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_flower_offload *cls_flower = type_data;
if (type != TC_SETUP_CLSFLOWER ||
- TC_H_MAJ(cls_flower->common.handle) != TC_H_MAJ(TC_H_INGRESS) ||
+ is_classid_clsact_ingress(cls_flower->common.classid) ||
!eth_proto_is_802_3(cls_flower->common.protocol) ||
cls_flower->common.chain_index)
return -EOPNOTSUPP;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 8c79011..78e78a6 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -914,7 +914,14 @@ static void dsa_slave_del_cls_matchall(struct net_device *dev,
static int dsa_slave_setup_tc_cls_matchall(struct net_device *dev,
struct tc_cls_matchall_offload *cls)
{
- bool ingress = TC_H_MAJ(cls->common.handle) == TC_H_MAJ(TC_H_INGRESS);
+ bool ingress;
+
+ if (is_classid_clsact_ingress(cls->common.classid))
+ ingress = true;
+ else if (is_classid_clsact_egress(cls->common.classid))
+ ingress = false;
+ else
+ return -EOPNOTSUPP;
if (cls->common.chain_index)
return -EOPNOTSUPP;
--
2.9.3
^ permalink raw reply related
* [patch net-next 4/5] net: sched: remove handle propagation down to the drivers
From: Jiri Pirko @ 2017-08-09 12:30 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw, andrew, vivien.didelot,
f.fainelli, jakub.kicinski, simon.horman, pieter.jansenvanvuuren,
oss-drivers, ganeshgr, jeffrey.t.kirsher, saeedm, matanb, leonro
In-Reply-To: <20170809123035.7663-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
There is no longer need to use handle in drivers, so remove it from
tc_cls_common_offload struct.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/net/pkt_cls.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 1f1de20..bd9dd79 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -406,7 +406,6 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)
#endif /* CONFIG_NET_CLS_IND */
struct tc_cls_common_offload {
- u32 handle;
u32 chain_index;
__be16 protocol;
u32 prio;
@@ -417,7 +416,6 @@ static inline void
tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
const struct tcf_proto *tp)
{
- cls_common->handle = tp->q->handle;
cls_common->chain_index = tp->chain->index;
cls_common->protocol = tp->protocol;
cls_common->prio = tp->prio;
--
2.9.3
^ permalink raw reply related
* [patch net-next 5/5] net: sched: remove cops->tcf_cl_offload
From: Jiri Pirko @ 2017-08-09 12:30 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw, andrew, vivien.didelot,
f.fainelli, jakub.kicinski, simon.horman, pieter.jansenvanvuuren,
oss-drivers, ganeshgr, jeffrey.t.kirsher, saeedm, matanb, leonro
In-Reply-To: <20170809123035.7663-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
cops->tcf_cl_offload is no longer needed, as the drivers check what they
can and cannot offload using the classid identify helpers. So remove this.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/net/pkt_cls.h | 14 +++-----------
include/net/sch_generic.h | 1 -
net/sched/cls_bpf.c | 4 ++--
net/sched/cls_flower.c | 8 ++++----
net/sched/cls_matchall.c | 4 ++--
net/sched/cls_u32.c | 8 ++++----
net/sched/sch_ingress.c | 12 ------------
7 files changed, 15 insertions(+), 36 deletions(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index bd9dd79..e80edd8 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -457,19 +457,12 @@ struct tc_cls_u32_offload {
};
};
-static inline bool tc_can_offload(const struct net_device *dev,
- const struct tcf_proto *tp)
+static inline bool tc_can_offload(const struct net_device *dev)
{
- const struct Qdisc *sch = tp->q;
- const struct Qdisc_class_ops *cops = sch->ops->cl_ops;
-
if (!(dev->features & NETIF_F_HW_TC))
return false;
if (!dev->netdev_ops->ndo_setup_tc)
return false;
- if (cops && cops->tcf_cl_offload)
- return cops->tcf_cl_offload(tp->classid);
-
return true;
}
@@ -478,12 +471,11 @@ static inline bool tc_skip_hw(u32 flags)
return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false;
}
-static inline bool tc_should_offload(const struct net_device *dev,
- const struct tcf_proto *tp, u32 flags)
+static inline bool tc_should_offload(const struct net_device *dev, u32 flags)
{
if (tc_skip_hw(flags))
return false;
- return tc_can_offload(dev, tp);
+ return tc_can_offload(dev);
}
static inline bool tc_skip_sw(u32 flags)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index e79f5ad..5865db9 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -156,7 +156,6 @@ struct Qdisc_class_ops {
/* Filter manipulation */
struct tcf_block * (*tcf_block)(struct Qdisc *, unsigned long);
- bool (*tcf_cl_offload)(u32 classid);
unsigned long (*bind_tcf)(struct Qdisc *, unsigned long,
u32 classid);
void (*unbind_tcf)(struct Qdisc *, unsigned long);
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index db17b68..6f2dffe 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -178,7 +178,7 @@ static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog,
(oldprog && tc_skip_sw(oldprog->gen_flags));
if (oldprog && oldprog->offloaded) {
- if (tc_should_offload(dev, tp, prog->gen_flags)) {
+ if (tc_should_offload(dev, prog->gen_flags)) {
cmd = TC_CLSBPF_REPLACE;
} else if (!tc_skip_sw(prog->gen_flags)) {
obj = oldprog;
@@ -187,7 +187,7 @@ static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog,
return -EINVAL;
}
} else {
- if (!tc_should_offload(dev, tp, prog->gen_flags))
+ if (!tc_should_offload(dev, prog->gen_flags))
return skip_sw ? -EINVAL : 0;
cmd = TC_CLSBPF_ADD;
}
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index d2551a0..052e902 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -227,7 +227,7 @@ static void fl_hw_destroy_filter(struct tcf_proto *tp, struct cls_fl_filter *f)
struct tc_cls_flower_offload cls_flower = {};
struct net_device *dev = f->hw_dev;
- if (!tc_can_offload(dev, tp))
+ if (!tc_can_offload(dev))
return;
tc_cls_common_offload_init(&cls_flower.common, tp);
@@ -246,9 +246,9 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
struct tc_cls_flower_offload cls_flower = {};
int err;
- if (!tc_can_offload(dev, tp)) {
+ if (!tc_can_offload(dev)) {
if (tcf_exts_get_dev(dev, &f->exts, &f->hw_dev) ||
- (f->hw_dev && !tc_can_offload(f->hw_dev, tp))) {
+ (f->hw_dev && !tc_can_offload(f->hw_dev))) {
f->hw_dev = dev;
return tc_skip_sw(f->flags) ? -EINVAL : 0;
}
@@ -281,7 +281,7 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f)
struct tc_cls_flower_offload cls_flower = {};
struct net_device *dev = f->hw_dev;
- if (!tc_can_offload(dev, tp))
+ if (!tc_can_offload(dev))
return;
tc_cls_common_offload_init(&cls_flower.common, tp);
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index d44e26f..d4dc387 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -92,7 +92,7 @@ static void mall_destroy(struct tcf_proto *tp)
if (!head)
return;
- if (tc_should_offload(dev, tp, head->flags))
+ if (tc_should_offload(dev, head->flags))
mall_destroy_hw_filter(tp, head, (unsigned long) head);
call_rcu(&head->rcu, mall_destroy_rcu);
@@ -172,7 +172,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
if (err)
goto err_set_parms;
- if (tc_should_offload(dev, tp, flags)) {
+ if (tc_should_offload(dev, flags)) {
err = mall_replace_hw_filter(tp, new, (unsigned long) new);
if (err) {
if (tc_skip_sw(flags))
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 5a3f781..af22742 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -433,7 +433,7 @@ static void u32_remove_hw_knode(struct tcf_proto *tp, u32 handle)
struct net_device *dev = tp->q->dev_queue->dev;
struct tc_cls_u32_offload cls_u32 = {};
- if (!tc_should_offload(dev, tp, 0))
+ if (!tc_should_offload(dev, 0))
return;
tc_cls_common_offload_init(&cls_u32.common, tp);
@@ -450,7 +450,7 @@ static int u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h,
struct tc_cls_u32_offload cls_u32 = {};
int err;
- if (!tc_should_offload(dev, tp, flags))
+ if (!tc_should_offload(dev, flags))
return tc_skip_sw(flags) ? -EINVAL : 0;
tc_cls_common_offload_init(&cls_u32.common, tp);
@@ -471,7 +471,7 @@ static void u32_clear_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h)
struct net_device *dev = tp->q->dev_queue->dev;
struct tc_cls_u32_offload cls_u32 = {};
- if (!tc_should_offload(dev, tp, 0))
+ if (!tc_should_offload(dev, 0))
return;
tc_cls_common_offload_init(&cls_u32.common, tp);
@@ -490,7 +490,7 @@ static int u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n,
struct tc_cls_u32_offload cls_u32 = {};
int err;
- if (!tc_should_offload(dev, tp, flags))
+ if (!tc_should_offload(dev, flags))
return tc_skip_sw(flags) ? -EINVAL : 0;
tc_cls_common_offload_init(&cls_u32.common, tp);
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index d8a9beb..a15c543 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -32,11 +32,6 @@ static unsigned long ingress_get(struct Qdisc *sch, u32 classid)
return TC_H_MIN(classid) + 1;
}
-static bool ingress_cl_offload(u32 classid)
-{
- return true;
-}
-
static unsigned long ingress_bind_filter(struct Qdisc *sch,
unsigned long parent, u32 classid)
{
@@ -103,7 +98,6 @@ static const struct Qdisc_class_ops ingress_class_ops = {
.put = ingress_put,
.walk = ingress_walk,
.tcf_block = ingress_tcf_block,
- .tcf_cl_offload = ingress_cl_offload,
.bind_tcf = ingress_bind_filter,
.unbind_tcf = ingress_put,
};
@@ -134,11 +128,6 @@ static unsigned long clsact_get(struct Qdisc *sch, u32 classid)
}
}
-static bool clsact_cl_offload(u32 classid)
-{
- return TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS);
-}
-
static unsigned long clsact_bind_filter(struct Qdisc *sch,
unsigned long parent, u32 classid)
{
@@ -198,7 +187,6 @@ static const struct Qdisc_class_ops clsact_class_ops = {
.put = ingress_put,
.walk = ingress_walk,
.tcf_block = clsact_tcf_block,
- .tcf_cl_offload = clsact_cl_offload,
.bind_tcf = clsact_bind_filter,
.unbind_tcf = ingress_put,
};
--
2.9.3
^ permalink raw reply related
* Re: [PATCH v06 15/36] uapi linux/socket.h: include sys/socket.h in user space
From: Arnd Bergmann @ 2017-08-09 12:32 UTC (permalink / raw)
To: Dmitry V. Levin
Cc: Mikko Rapeli, Linux Kernel Mailing List, Linux API, Networking
In-Reply-To: <20170808230041.GG10552-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
On Wed, Aug 9, 2017 at 1:00 AM, Dmitry V. Levin <ldv-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org> wrote:
> On Sun, Aug 06, 2017 at 06:44:06PM +0200, Mikko Rapeli wrote:
>> This libc header has sockaddr definition in user space.
>>
>> Fixes user space compilation errors like these from kernel headers including
>> only linux/socket.h:
>>
>> error: field ‘ifru_addr’ has incomplete type
>> struct sockaddr ifru_addr;
>> error: field ‘_sockaddr’ has incomplete type
>> struct sockaddr _sockaddr;
>> error: invalid application of ‘sizeof’ to incomplete type ‘struct sockaddr’
>>
>> With this following uapi headers now compile in user space:
>>
>> rdma/rdma_user_rxe.h
>> linux/vm_sockets.h
>> linux/ncp_fs.h
>> linux/nfc.h
>> linux/phonet.h
>>
>>
>> +#ifndef __KERNEL__
>> +#include <sys/socket.h>
>> +#endif
>
> This is scary because of infamous libc vs uapi interoperability issues.
> Couldn't we fix affected headers instead?
Yes, I think that would be better. Maybe we can introduce a
'struct __kernel_sockaddr' in include/uapi/linux/socket.h to
go along with __kernel_sa_family_t and __kernel_sockaddr_storage,
and then use those types in the other kernel headers?
Arnd
^ permalink raw reply
* Re: [PATCH v9 2/4] PCI: Disable PCIe Relaxed Ordering if unsupported
From: Casey Leedom @ 2017-08-09 12:33 UTC (permalink / raw)
To: Bjorn Helgaas, Ding Tianhong
Cc: ashok.raj@intel.com, bhelgaas@google.com, Michael Werner,
Ganesh GR, asit.k.mallick@intel.com, patrick.j.cramer@intel.com,
Suravee.Suthikulpanit@amd.com, Bob.Shaw@amd.com,
l.stach@pengutronix.de, amira@mellanox.com,
gabriele.paoloni@huawei.com, David.Laight@aculab.com,
jeffrey.t.kirsher@intel.com, catalin.marinas@arm.com,
will.deacon@arm.com, "mark.rutland@arm.com" <mark.r
In-Reply-To: <20170809022239.GP16580@bhelgaas-glaptop.roam.corp.google.com>
| From: Bjorn Helgaas <helgaas@kernel.org>
| Sent: Tuesday, August 8, 2017 7:22 PM
| ...
| and the caller should do something like this:
|
| if (pcie_relaxed_ordering_broken(pci_find_pcie_root_port(pdev)))
| adapter->flags |= ROOT_NO_RELAXED_ORDERING;
|
| That way it's obvious where the issue is, and it's obvious that the
| answer might be different for peer-to-peer transactions than it is for
| transactions to the root port, i.e., to coherent memory.
| ...
Which is back to something very close to what I initially suggested in my
first patch submission. Because you're right, this isn't about broken
Source Devices, it's about broken Completing Devices.
Unfortunately, as Alexander Duyck noted, in a Virtual Machine we won't be
able to see our Root Port in order to make this determination. (And in some
Hypervisor implementations I've seen, there's not even a synthetic Root Port
available to the VM at all, let alone read-only access to the real one.)
So the current scheme was developed of having the Hypervisor kernel traverse
down the PCIe Fabric when it finds a broken Root Port implementation (the
issue that we've mostly been primarily focused upon), and turning off the
PCIe Capability Device Control[Relaxed Ordering Enable]. This was to serve
two purposes:
1. Turn that off in order to prevent sending any Transaction Layer
Packets with the Relaxed Ordering Attribute to any Completer.
Which unfortunately would also prevent Peer-to-Peer use of the
Relaxed Ordering Attribute.
2. Act as a message to Device Drivers for those downstream devices
that the they were dealing with a broken Root Port implementation.
And this would work even for a driver in a VM with an attached
device since it would be able to see the PCIe Configuration Space
for the attached device.
I haven't been excited about any of this because:
A. While so far all of the examples we've talked about are broken
Root Port Completers, it's perfectly possible that other devices
could be broken -- say an NVMe Device which is not "Coherent
Memory". How would this fit into the framework APIs being
described?
B. I have yet to see a n example of how the currently proposed
API framework would be used in a hybrid environment where
TLPs to the Root Port would not use Relaxed Ordering, but TLPs
to a Peer would use Relaxed Ordering. So far its all been about
using a "big hammer" to completely disable the use of Relaxed
Ordering.
But the VM problem keeps cropping up over and over. A driver in a VM
doesn't have access to the Root Port to determine if its on a "Black List"
and our only way of communicating with the driver in the VM is to leave the
device in a particular state (i.e. initialize the PCIe Capability Device
Control[Relaxed Ordering Enable] to "off").
Oh, and also, on the current patch submission's focus on broken Root Port
implementations: one could suggest that even if we're stuck with the "Device
attached to a VM Conundrum", that what we should really be thinking about is
if ANY device within a PCIe Fabric has broken Relaxed Ordering completion
problems, and, if so, "poisoning" the entire containing PCIe Fabric by
turning off Relaxed Ordering Enable for every device, up, down sideways --
including the Root Port itself.
| ...
| This associates the message with the Requester that may potentially
| use relaxed ordering. But there's nothing wrong or unusual about the
| Requester; the issue is with the *Completer*, so I think the message
| should be in the quirk where we set PCI_DEV_FLAGS_NO_RELAXED_ORDERING.
| Maybe it should be both places; I dunno.
|
| This implementation assumes the device only initiates transactions to
| coherent memory, i.e., it assumes the device never does peer-to-peer
| DMA. I guess we'll have to wait and see if we trip over any
| peer-to-peer issues, then figure out how to handle them.
| ...
Yes, as soon as we want to implement the hybrid use of Relaxed Ordering I
mentioned above. And that the Intel document mentions itself.
Casey
^ permalink raw reply
* Re: Qdisc->u32_node - licence to kill
From: Jamal Hadi Salim @ 2017-08-09 12:40 UTC (permalink / raw)
To: Cong Wang, John Fastabend
Cc: Jiri Pirko, David Miller, Linux Kernel Network Developers, mlxsw
In-Reply-To: <CAM_iQpUZdv1sg+6jY862=GbWaC8x9XN9Ed-uaKi6_RT12sFj6w@mail.gmail.com>
On 17-08-07 07:21 PM, Cong Wang wrote:
> On Mon, Aug 7, 2017 at 12:54 PM, John Fastabend
> <john.fastabend@gmail.com> wrote:
>> On 08/07/2017 12:06 PM, Jiri Pirko wrote:
>>> Mon, Aug 07, 2017 at 07:47:14PM CEST, john.fastabend@gmail.com wrote:
>>>> On 08/07/2017 09:41 AM, Jiri Pirko wrote:
>>>>> Hi Jamal/Cong/David/all.
>>>>>
=
>>>
>>> Not correct. prio/pref is one level up priority, independent on specific
>>> cls implementation. You can have cls_u32 instance on prio 10 and
>>> cls_flower instance on prio 20. Both work.
>>
>> ah right, lets make sure I got this right then (its been awhile since I've
>> read this code). So the tcf_ctl_tfilter hook walks classifiers, inserting the
>> classifier by prio. Then tcf_classify walks the list of classifiers looking
>> for any matches, specifically any return codes it recognizes or a return code
>> greater than zero. u32 though has this link notion that allows users to jump
>> to other u32 classifiers that are in this list, because it has a global hash
>> table list. So the per prio classifier isolation is not true in u32 case.
>
> u32 filter supports multiple hash tables within a qdisc, struct
> tc_u_common is supposed to link them together. This has to be
> per qdisc because all of these hash tables belong to one qdisc
> and their ID's are unique within the qdisc.
>
I think historically this used to sit within the u32 code as a
static linked list; i cant recall why it got attached to the
qdisc.
Indeed, the idea is that hash tables can be added independently
without linking and then linked afterwards. They have to be held
somewhere in transient. And they have priorities (at least the
prios are used in the dump)
> I dislike it too, and I actually tried to improve it in the past,
> unfortunately didn't make any real progress. I think we can
> definitely make it less ugly, but I don't think we can totally
> get rid of it because of the design of u32.
>
> Similar for tp->data.
>
tp->q maybe harder to deal with. I agree with getting rid of
this dependency. Could this info be stored in the block instead?
cheers,
jamal
^ permalink raw reply
* [PATCH 0/4] net-next: dsa: fix flow dissection
From: John Crispin @ 2017-08-09 12:41 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
Sean Wang
Cc: Muciri Gatimu, netdev-u79uwXL29TY76Z2rM5mHXA,
Shashidhar Lakkavalli, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, John Crispin
RPS and probably other kernel features are currently broken on some if not
all DSA devices. The root cause of this is that skb_hash will call the
flow_dissector. At this point the skb still contains the magic switch
header and the skb->protocol field is not set up to the correct 802.3
value yet. By the time the tag specific code is called, removing the header
and properly setting the protocol an invalid hash is already set. In the
case of the mt7530 this will result in all flows always having the same
hash.
Changes since RFC:
* use a callback instead of static values
* add cover letter
John Crispin (4):
net-next: dsa: move struct dsa_device_ops to the global header file
net-next: dsa: add flow_dissect callback to struct dsa_device_ops
net-next: tag_mtk: add flow_dissect callback to the ops struct
net-next: dsa: fix flow dissection
include/net/dsa.h | 9 +++++++++
net/core/flow_dissector.c | 12 ++++++++++++
net/dsa/dsa_priv.h | 7 -------
net/dsa/tag_mtk.c | 14 ++++++++++++--
4 files changed, 33 insertions(+), 9 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH 2/4] net-next: dsa: add flow_dissect callback to struct dsa_device_ops
From: John Crispin @ 2017-08-09 12:41 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
Sean Wang
Cc: Muciri Gatimu, netdev-u79uwXL29TY76Z2rM5mHXA,
Shashidhar Lakkavalli, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, John Crispin
In-Reply-To: <20170809124119.24320-1-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
When the flow dissector first sees packets coming in on a DSA devices the
802.3 header wont be located where the code expects it to be as the tag
is still present. Adding this new callback allows a DSA device to provide a
new function that the flow_dissector can use to get the correct protocol
and offset of the network header.
Signed-off-by: Muciri Gatimu <muciri-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
include/net/dsa.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 65d7804c6f69..7f46b521313e 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -106,6 +106,8 @@ struct dsa_device_ops {
struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev);
+ int (*flow_dissect)(const struct sk_buff *skb, __be16 *proto,
+ int *offset);
};
struct dsa_switch_tree {
--
2.11.0
^ permalink raw reply related
* [PATCH 3/4] net-next: tag_mtk: add flow_dissect callback to the ops struct
From: John Crispin @ 2017-08-09 12:41 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
Sean Wang
Cc: netdev, linux-mediatek, linux-kernel, Muciri Gatimu,
Shashidhar Lakkavalli, John Crispin
In-Reply-To: <20170809124119.24320-1-john@phrozen.org>
The MT7530 inserts the 4 magic header in between the 802.3 address and
protocol field. The patch implements the callback that can be called by
the flow dissector to figure out the real protocol and offset of the
network header. With this patch applied we can properly parse the packet
and thus make hashing function properly.
Signed-off-by: Muciri Gatimu <muciri@openmesh.com>
Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli@openmesh.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
net/dsa/tag_mtk.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index 2f32b7ea3365..02163c045a96 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -87,7 +87,17 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
return skb;
}
+static int mtk_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+ int *offset)
+{
+ *offset = 4;
+ *proto = ((__be16 *)skb->data)[1];
+
+ return 0;
+}
+
const struct dsa_device_ops mtk_netdev_ops = {
- .xmit = mtk_tag_xmit,
- .rcv = mtk_tag_rcv,
+ .xmit = mtk_tag_xmit,
+ .rcv = mtk_tag_rcv,
+ .flow_dissect = mtk_tag_flow_dissect,
};
--
2.11.0
^ permalink raw reply related
* [PATCH 4/4] net-next: dsa: fix flow dissection
From: John Crispin @ 2017-08-09 12:41 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
Sean Wang
Cc: Muciri Gatimu, netdev-u79uwXL29TY76Z2rM5mHXA,
Shashidhar Lakkavalli, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, John Crispin
In-Reply-To: <20170809124119.24320-1-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
RPS and probably other kernel features are currently broken on some if not
all DSA devices. The root cause of this is that skb_hash will call the
flow_dissector. At this point the skb still contains the magic switch
header and the skb->protocol field is not set up to the correct 802.3
value yet. By the time the tag specific code is called, removing the header
and properly setting the protocol an invalid hash is already set. In the
case of the mt7530 this will result in all flows always having the same
hash.
Signed-off-by: Muciri Gatimu <muciri-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
---
net/core/flow_dissector.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 0cc672aba1f0..5b5be9577257 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -4,6 +4,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_vlan.h>
+#include <net/dsa.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/gre.h>
@@ -440,6 +441,17 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
skb->vlan_proto : skb->protocol;
nhoff = skb_network_offset(skb);
hlen = skb_headlen(skb);
+ if (unlikely(netdev_uses_dsa(skb->dev))) {
+ const struct dsa_device_ops *ops;
+ int offset;
+
+ ops = skb->dev->dsa_ptr->tag_ops;
+ if (ops->flow_dissect &&
+ !ops->flow_dissect(skb, &proto, &offset)) {
+ hlen -= offset;
+ nhoff += offset;
+ }
+ }
}
/* It is ensured by skb_flow_dissector_init() that control key will
--
2.11.0
^ permalink raw reply related
* [PATCH 1/4] net-next: dsa: move struct dsa_device_ops to the global header file
From: John Crispin @ 2017-08-09 12:41 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
Sean Wang
Cc: netdev, linux-mediatek, linux-kernel, Muciri Gatimu,
Shashidhar Lakkavalli, John Crispin
In-Reply-To: <20170809124119.24320-1-john@phrozen.org>
We need to access this struct from within the flow_dissector to fix
dissection for packets coming in on DSA devices.
Signed-off-by: Muciri Gatimu <muciri@openmesh.com>
Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli@openmesh.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
include/net/dsa.h | 7 +++++++
net/dsa/dsa_priv.h | 7 -------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index a4f66dbb4b7c..65d7804c6f69 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -101,6 +101,13 @@ struct dsa_platform_data {
struct packet_type;
+struct dsa_device_ops {
+ struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
+ struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt,
+ struct net_device *orig_dev);
+};
+
struct dsa_switch_tree {
struct list_head list;
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 68c63d4b989c..9fff7f4c8689 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -65,13 +65,6 @@ struct dsa_notifier_vlan_info {
int port;
};
-struct dsa_device_ops {
- struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
- struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *pt,
- struct net_device *orig_dev);
-};
-
struct dsa_slave_priv {
/* Copy of dp->ds->dst->tag_ops->xmit for faster access in hot path */
struct sk_buff * (*xmit)(struct sk_buff *skb,
--
2.11.0
^ permalink raw reply related
* Re: Qdisc->u32_node - licence to kill
From: Jiri Pirko @ 2017-08-09 12:48 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: Cong Wang, John Fastabend, David Miller,
Linux Kernel Network Developers, mlxsw
In-Reply-To: <c296f4c2-3509-a162-e972-42c2e81434aa@mojatatu.com>
Wed, Aug 09, 2017 at 02:40:30PM CEST, jhs@mojatatu.com wrote:
>On 17-08-07 07:21 PM, Cong Wang wrote:
>> On Mon, Aug 7, 2017 at 12:54 PM, John Fastabend
>> <john.fastabend@gmail.com> wrote:
>> > On 08/07/2017 12:06 PM, Jiri Pirko wrote:
>> > > Mon, Aug 07, 2017 at 07:47:14PM CEST, john.fastabend@gmail.com wrote:
>> > > > On 08/07/2017 09:41 AM, Jiri Pirko wrote:
>> > > > > Hi Jamal/Cong/David/all.
>> > > > >
>=
>> > >
>> > > Not correct. prio/pref is one level up priority, independent on specific
>> > > cls implementation. You can have cls_u32 instance on prio 10 and
>> > > cls_flower instance on prio 20. Both work.
>> >
>> > ah right, lets make sure I got this right then (its been awhile since I've
>> > read this code). So the tcf_ctl_tfilter hook walks classifiers, inserting the
>> > classifier by prio. Then tcf_classify walks the list of classifiers looking
>> > for any matches, specifically any return codes it recognizes or a return code
>> > greater than zero. u32 though has this link notion that allows users to jump
>> > to other u32 classifiers that are in this list, because it has a global hash
>> > table list. So the per prio classifier isolation is not true in u32 case.
>>
>> u32 filter supports multiple hash tables within a qdisc, struct
>> tc_u_common is supposed to link them together. This has to be
>> per qdisc because all of these hash tables belong to one qdisc
>> and their ID's are unique within the qdisc.
>>
>
>I think historically this used to sit within the u32 code as a
>static linked list; i cant recall why it got attached to the
>qdisc.
>Indeed, the idea is that hash tables can be added independently
>without linking and then linked afterwards. They have to be held
>somewhere in transient. And they have priorities (at least the
>prios are used in the dump)
>
>> I dislike it too, and I actually tried to improve it in the past,
>> unfortunately didn't make any real progress. I think we can
>> definitely make it less ugly, but I don't think we can totally
>> get rid of it because of the design of u32.
>>
>> Similar for tp->data.
>>
>
>tp->q maybe harder to deal with. I agree with getting rid of
>this dependency. Could this info be stored in the block instead?
Yeah, I will have to do that. I just wanted to get rid of it if possible :/
>
>cheers,
>jamal
^ permalink raw reply
* [PATCH iproute2 net-next 0/3] Add support for SRv6 local segment processing
From: David Lebrun @ 2017-08-09 13:16 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
This patch series adds support and documentation for the seg6local
lightweight tunnel, enabling to perform operations to SR-enabled packets
based on their active segment.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
David Lebrun (3):
iproute: add helper functions for SRH processing
iproute: add support for SRv6 local segment processing
man: add documentation for seg6local lwt
ip/iproute.c | 2 +-
ip/iproute_lwtunnel.c | 354 ++++++++++++++++++++++++++++++++++++++++++-------
man/man8/ip-route.8.in | 62 ++++++++-
3 files changed, 368 insertions(+), 50 deletions(-)
--
2.10.2
^ permalink raw reply
* [PATCH iproute2 net-next 1/3] iproute: add helper functions for SRH processing
From: David Lebrun @ 2017-08-09 13:16 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <20170809131701.21304-1-david.lebrun@uclouvain.be>
This patch adds two helper functions to print and parse
Segment Routing Headers.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
ip/iproute_lwtunnel.c | 124 +++++++++++++++++++++++++++++---------------------
1 file changed, 72 insertions(+), 52 deletions(-)
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 5c0c7d1..16d2584 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -83,24 +83,10 @@ static int read_encap_type(const char *name)
return LWTUNNEL_ENCAP_NONE;
}
-static void print_encap_seg6(FILE *fp, struct rtattr *encap)
+static void print_srh(FILE *fp, struct ipv6_sr_hdr *srh)
{
- struct rtattr *tb[SEG6_IPTUNNEL_MAX+1];
- struct seg6_iptunnel_encap *tuninfo;
- struct ipv6_sr_hdr *srh;
int i;
- parse_rtattr_nested(tb, SEG6_IPTUNNEL_MAX, encap);
-
- if (!tb[SEG6_IPTUNNEL_SRH])
- return;
-
- tuninfo = RTA_DATA(tb[SEG6_IPTUNNEL_SRH]);
- fprintf(fp, "mode %s ",
- (tuninfo->mode == SEG6_IPTUN_MODE_ENCAP) ? "encap" : "inline");
-
- srh = tuninfo->srh;
-
fprintf(fp, "segs %d [ ", srh->first_segment + 1);
for (i = srh->first_segment; i >= 0; i--)
@@ -118,6 +104,23 @@ static void print_encap_seg6(FILE *fp, struct rtattr *encap)
}
}
+static void print_encap_seg6(FILE *fp, struct rtattr *encap)
+{
+ struct rtattr *tb[SEG6_IPTUNNEL_MAX+1];
+ struct seg6_iptunnel_encap *tuninfo;
+
+ parse_rtattr_nested(tb, SEG6_IPTUNNEL_MAX, encap);
+
+ if (!tb[SEG6_IPTUNNEL_SRH])
+ return;
+
+ tuninfo = RTA_DATA(tb[SEG6_IPTUNNEL_SRH]);
+ fprintf(fp, "mode %s ",
+ (tuninfo->mode == SEG6_IPTUN_MODE_ENCAP) ? "encap" : "inline");
+
+ print_srh(fp, tuninfo->srh);
+}
+
static void print_encap_mpls(FILE *fp, struct rtattr *encap)
{
struct rtattr *tb[MPLS_IPTUNNEL_MAX+1];
@@ -290,6 +293,55 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type,
}
}
+static struct ipv6_sr_hdr *parse_srh(char *segbuf, int hmac, bool encap)
+{
+ struct ipv6_sr_hdr *srh;
+ int nsegs = 0;
+ int srhlen;
+ char *s;
+ int i;
+
+ s = segbuf;
+ for (i = 0; *s; *s++ == ',' ? i++ : *s);
+ nsegs = i + 1;
+
+ if (!encap)
+ nsegs++;
+
+ srhlen = 8 + 16*nsegs;
+
+ if (hmac)
+ srhlen += 40;
+
+ srh = malloc(srhlen);
+ memset(srh, 0, srhlen);
+
+ srh->hdrlen = (srhlen >> 3) - 1;
+ srh->type = 4;
+ srh->segments_left = nsegs - 1;
+ srh->first_segment = nsegs - 1;
+
+ if (hmac)
+ srh->flags |= SR6_FLAG1_HMAC;
+
+ i = srh->first_segment;
+ for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
+ inet_get_addr(s, NULL, &srh->segments[i]);
+ i--;
+ }
+
+ if (hmac) {
+ struct sr6_tlv_hmac *tlv;
+
+ tlv = (struct sr6_tlv_hmac *)((char *)srh + srhlen - 40);
+ tlv->tlvhdr.type = SR6_TLV_HMAC;
+ tlv->tlvhdr.len = 38;
+ tlv->hmackeyid = htonl(hmac);
+ }
+
+ return srh;
+}
+
static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
char ***argvp)
{
@@ -301,10 +353,7 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
int argc = *argcp;
int encap = -1;
__u32 hmac = 0;
- int nsegs = 0;
int srhlen;
- char *s;
- int i;
while (argc > 0) {
if (strcmp(*argv, "mode") == 0) {
@@ -338,17 +387,8 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
argc--; argv++;
}
- s = segbuf;
- for (i = 0; *s; *s++ == ',' ? i++ : *s);
- nsegs = i + 1;
-
- if (!encap)
- nsegs++;
-
- srhlen = 8 + 16*nsegs;
-
- if (hmac)
- srhlen += 40;
+ srh = parse_srh(segbuf, hmac, encap);
+ srhlen = (srh->hdrlen + 1) << 3;
tuninfo = malloc(sizeof(*tuninfo) + srhlen);
memset(tuninfo, 0, sizeof(*tuninfo) + srhlen);
@@ -358,33 +398,13 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
else
tuninfo->mode = SEG6_IPTUN_MODE_INLINE;
- srh = tuninfo->srh;
- srh->hdrlen = (srhlen >> 3) - 1;
- srh->type = 4;
- srh->segments_left = nsegs - 1;
- srh->first_segment = nsegs - 1;
-
- if (hmac)
- srh->flags |= SR6_FLAG1_HMAC;
-
- i = srh->first_segment;
- for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
- inet_get_addr(s, NULL, &srh->segments[i]);
- i--;
- }
-
- if (hmac) {
- struct sr6_tlv_hmac *tlv;
-
- tlv = (struct sr6_tlv_hmac *)((char *)srh + srhlen - 40);
- tlv->tlvhdr.type = SR6_TLV_HMAC;
- tlv->tlvhdr.len = 38;
- tlv->hmackeyid = htonl(hmac);
- }
+ memcpy(tuninfo->srh, srh, srhlen);
rta_addattr_l(rta, len, SEG6_IPTUNNEL_SRH, tuninfo,
sizeof(*tuninfo) + srhlen);
+
free(tuninfo);
+ free(srh);
*argcp = argc + 1;
*argvp = argv - 1;
--
2.10.2
^ permalink raw reply related
* [PATCH iproute2 net-next 3/3] man: add documentation for seg6local lwt
From: David Lebrun @ 2017-08-09 13:17 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <20170809131701.21304-1-david.lebrun@uclouvain.be>
This patch adds documentation in the ip-route man page
about the seg6local lightweight tunnel.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
man/man8/ip-route.8.in | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
index fc28492..11dd9d0 100644
--- a/man/man8/ip-route.8.in
+++ b/man/man8/ip-route.8.in
@@ -177,7 +177,7 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.ti -8
.IR ENCAP " := [ "
-.IR MPLS " | " IP " | " BPF " | " SEG6 " ] "
+.IR MPLS " | " IP " | " BPF " | " SEG6 " | " SEG6LOCAL " ] "
.ti -8
.IR ENCAP_MPLS " := "
@@ -221,6 +221,13 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.IR KEYID " ]"
.ti -8
+.IR ENCAP_SEG6LOCAL " := "
+.B seg6local
+.BR action
+.IR SEG6_ACTION " [ "
+.IR SEG6_ACTION_PARAM " ] "
+
+.ti -8
.IR ROUTE_GET_FLAGS " := "
.BR " [ "
.BR fibmatch
@@ -674,6 +681,9 @@ is a string specifying the supported encapsulation type. Namely:
.sp
.BI seg6
- encapsulation type IPv6 Segment Routing
+.sp
+.BI seg6local
+- local SRv6 segment processing
.in -8
.I ENCAPHDR
@@ -749,6 +759,56 @@ is a set of encapsulation attributes specific to the
.in -2
.sp
+.B seg6local
+.in +2
+.IR SEG6_ACTION " [ "
+.IR SEG6_ACTION_PARAM " ] "
+- Operation to perform on matching packets.
+The following actions are currently supported (\fB4.14+ only\fR).
+.in +2
+
+.B End
+- Regular SRv6 processing as intermediate segment endpoint.
+This action only accepts packets with a non-zero Segments Left
+value. Other matching packets are dropped.
+
+.B End.X nh6
+.I NEXTHOP
+- Regular SRv6 processing as intermediate segment endpoint.
+Additionally, forward processed packets to given next-hop.
+This action only accepts packets with a non-zero Segments Left
+value. Other matching packets are dropped.
+
+.B End.DX6 nh6
+.I NEXTHOP
+- Decapsulate inner IPv6 packet and forward it to the
+specified next-hop. If the argument is set to ::, then
+the next-hop is selected according to the local selection
+rules. This action only accepts packets with either a zero Segments
+Left value or no SRH at all, and an inner IPv6 packet. Other
+matching packets are dropped.
+
+.B End.B6 srh segs
+.IR SEGMENTS " [ "
+.B hmac
+.IR KEYID " ] "
+- Insert the specified SRH immediately after the IPv6 header,
+update the DA with the first segment of the newly inserted SRH,
+then forward the resulting packet. The original SRH is not
+modified. This action only accepts packets with a non-zero
+Segments Left value. Other matching packets are dropped.
+
+.B End.B6.Encaps srh segs
+.IR SEGMENTS " [ "
+.B hmac
+.IR KEYID " ] "
+- Regular SRv6 processing as intermediate segment endpoint.
+Additionally, encapsulate the matching packet within an outer IPv6 header
+followed by the specified SRH. The destination address of the outer IPv6
+header is set to the first segment of the new SRH. The source
+address is set as described in \fBip-sr\fR(8).
+.in -4
+
.in -8
.TP
--
2.10.2
^ permalink raw reply related
* [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing
From: David Lebrun @ 2017-08-09 13:17 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <20170809131701.21304-1-david.lebrun@uclouvain.be>
This patch adds support for the seg6local lightweight tunnel
("ip route add ... encap seg6local ...").
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
ip/iproute.c | 2 +-
ip/iproute_lwtunnel.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 239 insertions(+), 1 deletion(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index cb695ad..7a37df5 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -100,7 +100,7 @@ static void usage(void)
fprintf(stderr, "TIME := NUMBER[s|ms]\n");
fprintf(stderr, "BOOL := [1|0]\n");
fprintf(stderr, "FEATURES := ecn\n");
- fprintf(stderr, "ENCAPTYPE := [ mpls | ip | ip6 | seg6 ]\n");
+ fprintf(stderr, "ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local ]\n");
fprintf(stderr, "ENCAPHDR := [ MPLSLABEL | SEG6HDR ]\n");
fprintf(stderr, "SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]\n");
fprintf(stderr, "SEGMODE := [ encap | inline ]\n");
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 16d2584..efea313 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -29,6 +29,8 @@
#include <linux/seg6.h>
#include <linux/seg6_iptunnel.h>
#include <linux/seg6_hmac.h>
+#include <linux/seg6_local.h>
+#include <net/if.h>
static const char *format_encap_type(int type)
{
@@ -45,6 +47,8 @@ static const char *format_encap_type(int type)
return "bpf";
case LWTUNNEL_ENCAP_SEG6:
return "seg6";
+ case LWTUNNEL_ENCAP_SEG6_LOCAL:
+ return "seg6local";
default:
return "unknown";
}
@@ -77,6 +81,8 @@ static int read_encap_type(const char *name)
return LWTUNNEL_ENCAP_BPF;
else if (strcmp(name, "seg6") == 0)
return LWTUNNEL_ENCAP_SEG6;
+ else if (strcmp(name, "seg6local") == 0)
+ return LWTUNNEL_ENCAP_SEG6_LOCAL;
else if (strcmp(name, "help") == 0)
encap_type_usage();
@@ -121,6 +127,124 @@ static void print_encap_seg6(FILE *fp, struct rtattr *encap)
print_srh(fp, tuninfo->srh);
}
+static const char *format_action_type(int action)
+{
+ switch (action) {
+ case SEG6_LOCAL_ACTION_END:
+ return "End";
+ case SEG6_LOCAL_ACTION_END_X:
+ return "End.X";
+ case SEG6_LOCAL_ACTION_END_T:
+ return "End.T";
+ case SEG6_LOCAL_ACTION_END_DX2:
+ return "End.DX2";
+ case SEG6_LOCAL_ACTION_END_DX6:
+ return "End.DX6";
+ case SEG6_LOCAL_ACTION_END_DX4:
+ return "End.DX4";
+ case SEG6_LOCAL_ACTION_END_DT6:
+ return "End.DT6";
+ case SEG6_LOCAL_ACTION_END_DT4:
+ return "End.DT4";
+ case SEG6_LOCAL_ACTION_END_B6:
+ return "End.B6";
+ case SEG6_LOCAL_ACTION_END_B6_ENCAP:
+ return "End.B6.Encaps";
+ case SEG6_LOCAL_ACTION_END_BM:
+ return "End.BM";
+ case SEG6_LOCAL_ACTION_END_S:
+ return "End.S";
+ case SEG6_LOCAL_ACTION_END_AS:
+ return "End.AS";
+ case SEG6_LOCAL_ACTION_END_AM:
+ return "End.AM";
+ default:
+ return "unknown";
+ }
+}
+
+static int read_action_type(const char *name)
+{
+ if (strcmp(name, "End") == 0)
+ return SEG6_LOCAL_ACTION_END;
+ else if (strcmp(name, "End.X") == 0)
+ return SEG6_LOCAL_ACTION_END_X;
+ else if (strcmp(name, "End.T") == 0)
+ return SEG6_LOCAL_ACTION_END_T;
+ else if (strcmp(name, "End.DX2") == 0)
+ return SEG6_LOCAL_ACTION_END_DX2;
+ else if (strcmp(name, "End.DX6") == 0)
+ return SEG6_LOCAL_ACTION_END_DX6;
+ else if (strcmp(name, "End.DX4") == 0)
+ return SEG6_LOCAL_ACTION_END_DX4;
+ else if (strcmp(name, "End.DT6") == 0)
+ return SEG6_LOCAL_ACTION_END_DT6;
+ else if (strcmp(name, "End.DT4") == 0)
+ return SEG6_LOCAL_ACTION_END_DT4;
+ else if (strcmp(name, "End.B6") == 0)
+ return SEG6_LOCAL_ACTION_END_B6;
+ else if (strcmp(name, "End.B6.Encaps") == 0)
+ return SEG6_LOCAL_ACTION_END_B6_ENCAP;
+ else if (strcmp(name, "End.BM") == 0)
+ return SEG6_LOCAL_ACTION_END_BM;
+ else if (strcmp(name, "End.S") == 0)
+ return SEG6_LOCAL_ACTION_END_S;
+ else if (strcmp(name, "End.AS") == 0)
+ return SEG6_LOCAL_ACTION_END_AS;
+ else if (strcmp(name, "End.AM") == 0)
+ return SEG6_LOCAL_ACTION_END_AM;
+
+ return SEG6_LOCAL_ACTION_UNSPEC;
+}
+
+static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
+{
+ struct rtattr *tb[SEG6_LOCAL_MAX + 1];
+ char ifbuf[IFNAMSIZ];
+ int action;
+
+ parse_rtattr_nested(tb, SEG6_LOCAL_MAX, encap);
+
+ if (!tb[SEG6_LOCAL_ACTION])
+ return;
+
+ action = rta_getattr_u32(tb[SEG6_LOCAL_ACTION]);
+
+ fprintf(fp, "action %s ", format_action_type(action));
+
+ if (tb[SEG6_LOCAL_SRH]) {
+ fprintf(fp, "srh ");
+ print_srh(fp, RTA_DATA(tb[SEG6_LOCAL_SRH]));
+ }
+
+ if (tb[SEG6_LOCAL_TABLE])
+ fprintf(fp, "table %u ", rta_getattr_u32(tb[SEG6_LOCAL_TABLE]));
+
+ if (tb[SEG6_LOCAL_NH4]) {
+ fprintf(fp, "nh4 %s ",
+ rt_addr_n2a_rta(AF_INET, tb[SEG6_LOCAL_NH4]));
+ }
+
+ if (tb[SEG6_LOCAL_NH6]) {
+ fprintf(fp, "nh6 %s ",
+ rt_addr_n2a_rta(AF_INET6, tb[SEG6_LOCAL_NH6]));
+ }
+
+ if (tb[SEG6_LOCAL_IIF]) {
+ int iif = rta_getattr_u32(tb[SEG6_LOCAL_IIF]);
+
+ fprintf(fp, "iif %s ",
+ if_indextoname(iif, ifbuf) ?: "<unknown>");
+ }
+
+ if (tb[SEG6_LOCAL_OIF]) {
+ int oif = rta_getattr_u32(tb[SEG6_LOCAL_OIF]);
+
+ fprintf(fp, "oif %s ",
+ if_indextoname(oif, ifbuf) ?: "<unknown>");
+ }
+}
+
static void print_encap_mpls(FILE *fp, struct rtattr *encap)
{
struct rtattr *tb[MPLS_IPTUNNEL_MAX+1];
@@ -290,6 +414,9 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type,
case LWTUNNEL_ENCAP_SEG6:
print_encap_seg6(fp, encap);
break;
+ case LWTUNNEL_ENCAP_SEG6_LOCAL:
+ print_encap_seg6local(fp, encap);
+ break;
}
}
@@ -412,6 +539,114 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
return 0;
}
+static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
+ char ***argvp)
+{
+ int segs_ok = 0, hmac_ok = 0, table_ok = 0, nh4_ok = 0, nh6_ok = 0;
+ int iif_ok = 0, oif_ok = 0, action_ok = 0, srh_ok = 0;
+ __u32 action = 0, table, iif, oif;
+ struct ipv6_sr_hdr *srh;
+ char **argv = *argvp;
+ int argc = *argcp;
+ char segbuf[1024];
+ inet_prefix addr;
+ __u32 hmac = 0;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "action") == 0) {
+ NEXT_ARG();
+ if (action_ok++)
+ duparg2("action", *argv);
+ action = read_action_type(*argv);
+ if (!action)
+ invarg("\"action\" value is invalid\n", *argv);
+ rta_addattr32(rta, len, SEG6_LOCAL_ACTION, action);
+ } else if (strcmp(*argv, "table") == 0) {
+ NEXT_ARG();
+ if (table_ok++)
+ duparg2("table", *argv);
+ get_u32(&table, *argv, 0);
+ rta_addattr32(rta, len, SEG6_LOCAL_TABLE, table);
+ } else if (strcmp(*argv, "nh4") == 0) {
+ NEXT_ARG();
+ if (nh4_ok++)
+ duparg2("nh4", *argv);
+ get_addr(&addr, *argv, AF_INET);
+ rta_addattr_l(rta, len, SEG6_LOCAL_NH4, &addr.data,
+ addr.bytelen);
+ } else if (strcmp(*argv, "nh6") == 0) {
+ NEXT_ARG();
+ if (nh6_ok++)
+ duparg2("nh6", *argv);
+ get_addr(&addr, *argv, AF_INET6);
+ rta_addattr_l(rta, len, SEG6_LOCAL_NH6, &addr.data,
+ addr.bytelen);
+ } else if (strcmp(*argv, "iif") == 0) {
+ NEXT_ARG();
+ if (iif_ok++)
+ duparg2("iif", *argv);
+ iif = if_nametoindex(*argv);
+ if (!iif)
+ invarg("\"iif\" interface not found\n", *argv);
+ rta_addattr32(rta, len, SEG6_LOCAL_IIF, iif);
+ } else if (strcmp(*argv, "oif") == 0) {
+ NEXT_ARG();
+ if (oif_ok++)
+ duparg2("oif", *argv);
+ oif = if_nametoindex(*argv);
+ if (!oif)
+ invarg("\"oif\" interface not found\n", *argv);
+ rta_addattr32(rta, len, SEG6_LOCAL_OIF, oif);
+ } else if (strcmp(*argv, "srh") == 0) {
+ NEXT_ARG();
+ if (srh_ok++)
+ duparg2("srh", *argv);
+ if (strcmp(*argv, "segs") != 0)
+ invarg("missing \"segs\" attribute for srh\n",
+ *argv);
+ NEXT_ARG();
+ if (segs_ok++)
+ duparg2("segs", *argv);
+ strncpy(segbuf, *argv, 1024);
+ segbuf[1023] = 0;
+ if (!NEXT_ARG_OK())
+ break;
+ NEXT_ARG();
+ if (strcmp(*argv, "hmac") == 0) {
+ NEXT_ARG();
+ if (hmac_ok++)
+ duparg2("hmac", *argv);
+ get_u32(&hmac, *argv, 0);
+ } else {
+ continue;
+ }
+ } else {
+ break;
+ }
+ argc--; argv++;
+ }
+
+ if (!action) {
+ fprintf(stderr, "Missing action type\n");
+ exit(-1);
+ }
+
+ if (srh_ok) {
+ int srhlen;
+
+ srh = parse_srh(segbuf, hmac,
+ action == SEG6_LOCAL_ACTION_END_B6_ENCAP);
+ srhlen = (srh->hdrlen + 1) << 3;
+ rta_addattr_l(rta, len, SEG6_LOCAL_SRH, srh, srhlen);
+ free(srh);
+ }
+
+ *argcp = argc + 1;
+ *argvp = argv - 1;
+
+ return 0;
+}
+
static int parse_encap_mpls(struct rtattr *rta, size_t len,
int *argcp, char ***argvp)
{
@@ -771,6 +1006,9 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)
case LWTUNNEL_ENCAP_SEG6:
parse_encap_seg6(rta, len, &argc, &argv);
break;
+ case LWTUNNEL_ENCAP_SEG6_LOCAL:
+ parse_encap_seg6local(rta, len, &argc, &argv);
+ break;
default:
fprintf(stderr, "Error: unsupported encap type\n");
break;
--
2.10.2
^ permalink raw reply related
* Re: [PATCH v9 2/4] PCI: Disable PCIe Relaxed Ordering if unsupported
From: Ding Tianhong @ 2017-08-09 13:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: leedom, ashok.raj, bhelgaas, werner, ganeshgr, asit.k.mallick,
patrick.j.cramer, Suravee.Suthikulpanit, Bob.Shaw, l.stach, amira,
gabriele.paoloni, David.Laight, jeffrey.t.kirsher,
catalin.marinas, will.deacon, mark.rutland, robin.murphy, davem,
alexander.duyck, linux-arm-kernel, netdev, linux-pci,
linux-kernel, linuxarm
In-Reply-To: <20170809022239.GP16580@bhelgaas-glaptop.roam.corp.google.com>
Hi Bjorn:
On 2017/8/9 10:22, Bjorn Helgaas wrote:
> On Sat, Aug 05, 2017 at 03:15:11PM +0800, Ding Tianhong wrote:
>> When bit4 is set in the PCIe Device Control register, it indicates
>> whether the device is permitted to use relaxed ordering.
>> On some platforms using relaxed ordering can have performance issues or
>> due to erratum can cause data-corruption. In such cases devices must avoid
>> using relaxed ordering.
>>
>> This patch checks if there is any node in the hierarchy that indicates that
>> using relaxed ordering is not safe.
>
> I think you only check the devices between the root port and the
> target device. For example, you don't check siblings or cousins of
> the target device.
>
OK, update the description.
>> In such cases the patch turns off the
>> relaxed ordering by clearing the eapability for this device.
>
> s/eapability/capability/
>
>> And if the
>> device is probably running in a guest machine, we should do nothing.
>
> I don't know what this sentence means. "Probably running in a guest
> machine" doesn't really make sense, and there's nothing in your patch
> that explicitly checks for being in a guest machine.
>
Alex noticed that we should do nothing if in the virtual machine because
the Root Complex is NULL at that time, so I think this word should be more
clearly here.
>> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
>> Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>
>> Acked-by: Ashok Raj <ashok.raj@intel.com>
>> ---
>> drivers/pci/pci.c | 29 +++++++++++++++++++++++++++++
>> drivers/pci/probe.c | 37 +++++++++++++++++++++++++++++++++++++
>> include/linux/pci.h | 2 ++
>> 3 files changed, 68 insertions(+)
>>
>> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
>> index af0cc34..4f9d7c1 100644
>> --- a/drivers/pci/pci.c
>> +++ b/drivers/pci/pci.c
>> @@ -4854,6 +4854,35 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
>> EXPORT_SYMBOL(pcie_set_mps);
>>
>> /**
>> + * pcie_clear_relaxed_ordering - clear PCI Express relaxed ordering bit
>> + * @dev: PCI device to query
>> + *
>> + * If possible clear relaxed ordering
>
> Why "If possible"? The bit is required to be RW or hardwired to zero,
> so PCI_EXP_DEVCTL_RELAX_EN should *always* be zero when this returns.
>
OK
>> + */
>> +int pcie_clear_relaxed_ordering(struct pci_dev *dev)
>> +{
...
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> .
>
^ permalink raw reply
* Re: [PATCH 3/3] net: rxrpc: Replace time_t type with time64_t type
From: David Howells @ 2017-08-09 13:26 UTC (permalink / raw)
To: Arnd Bergmann
Cc: dhowells, Baolin Wang, David Miller, james.l.morris,
Serge E. Hallyn, marc.dionne, Dan Carpenter, Jason A. Donenfeld,
Mark Brown, keyrings, Linux Kernel Mailing List, LSM List,
Networking
In-Reply-To: <CAK8P3a3L11rXAV8-hE1fNtAZyMBNnQneRm5g7F8VDmk7HjQV4A@mail.gmail.com>
Arnd Bergmann <arnd@arndb.de> wrote:
> Do you know which format is used in practice? Are both kad and k5 common
> among rxrpc users?
The aklog program I'm using uses the non-XDR interface to push a Kerberos 5
ticket to the kernel, so it doesn't actually invoke rxrpc_preparse_xdr() from
rxrpc_preparse().
David
^ permalink raw reply
* Re: [PATCH v9 2/4] PCI: Disable PCIe Relaxed Ordering if unsupported
From: Ding Tianhong @ 2017-08-09 13:42 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: mark.rutland, gabriele.paoloni, asit.k.mallick, catalin.marinas,
will.deacon, linuxarm, alexander.duyck, ashok.raj,
jeffrey.t.kirsher, linux-pci, ganeshgr, Bob.Shaw, leedom,
patrick.j.cramer, bhelgaas, werner, linux-arm-kernel, amira,
netdev, linux-kernel, David.Laight, Suravee.Suthikulpanit,
robin.murphy, davem, l.stach
In-Reply-To: <20170809032503.GB7191@bhelgaas-glaptop.roam.corp.google.com>
On 2017/8/9 11:25, Bjorn Helgaas wrote:
> On Tue, Aug 08, 2017 at 09:22:39PM -0500, Bjorn Helgaas wrote:
>> On Sat, Aug 05, 2017 at 03:15:11PM +0800, Ding Tianhong wrote:
>>> When bit4 is set in the PCIe Device Control register, it indicates
> After looking at the driver, I wonder if it would be simpler like
> this:
>
> int pcie_relaxed_ordering_enabled(struct pci_dev *dev)
> {
> u16 ctl;
>
> pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
> return ctl & PCI_EXP_DEVCTL_RELAX_EN;
> }
> EXPORT_SYMBOL(pcie_relaxed_ordering_enabled);
>
> static void pci_configure_relaxed_ordering(struct pci_dev *dev)
> {
> struct pci_dev *root;
>
> if (dev->is_virtfn)
> return; /* PCI_EXP_DEVCTL_RELAX_EN is RsvdP in VFs */
>
> if (!pcie_relaxed_ordering_enabled(dev))
> return;
>
> /*
> * For now, we only deal with Relaxed Ordering issues with Root
> * Ports. Peer-to-peer DMA is another can of worms.
> */
> root = pci_find_pcie_root_port(dev);
> if (!root)
> return;
>
> if (root->relaxed_ordering_broken)
> pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
> PCI_EXP_DEVCTL_RELAX_EN);
> }
>
> This doesn't check every intervening switch, but I don't think we know
> about any issues except with root ports.
>
Yes
> And the driver could do:
>
> if (!pcie_relaxed_ordering_enabled(pdev))
> adapter->flags |= ROOT_NO_RELAXED_ORDERING;
>
> The driver code wouldn't show anything about coherent memory vs.
> peer-to-peer, but we really don't have a clue about how to handle that
> yet anyway.
>
> I guess this is back to exactly what you proposed, except that I
> changed the name of pcie_relaxed_ordering_supported() to
> pcie_relaxed_ordering_enabled(), which I think is slightly more
> specific from the device's point of view.
>
OK, looks like we reach a consensus finally, I will follow your new opinion and resend, thanks.
Ding
> Bjorn
>
> .
>
^ permalink raw reply
* Re: [PATCH 1/4] net-next: dsa: move struct dsa_device_ops to the global header file
From: Andrew Lunn @ 2017-08-09 13:45 UTC (permalink / raw)
To: John Crispin
Cc: Florian Fainelli, Muciri Gatimu, Vivien Didelot,
netdev-u79uwXL29TY76Z2rM5mHXA, Sean Wang,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Shashidhar Lakkavalli, David S . Miller
In-Reply-To: <20170809124119.24320-2-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
On Wed, Aug 09, 2017 at 02:41:16PM +0200, John Crispin wrote:
> We need to access this struct from within the flow_dissector to fix
> dissection for packets coming in on DSA devices.
>
> Signed-off-by: Muciri Gatimu <muciri-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
> Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
Hi John
Please add the Reviewed-by: tags you receive from previous
versions. It makes it easier for reviewers to see what actually needs
reviewing.
Thanks
Andrew
^ permalink raw reply
* Re: [PATCH 2/4] net-next: dsa: add flow_dissect callback to struct dsa_device_ops
From: Andrew Lunn @ 2017-08-09 13:51 UTC (permalink / raw)
To: John Crispin
Cc: Florian Fainelli, Muciri Gatimu, Vivien Didelot,
netdev-u79uwXL29TY76Z2rM5mHXA, Sean Wang,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Shashidhar Lakkavalli, David S . Miller
In-Reply-To: <20170809124119.24320-3-john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
On Wed, Aug 09, 2017 at 02:41:17PM +0200, John Crispin wrote:
> When the flow dissector first sees packets coming in on a DSA devices the
> 802.3 header wont be located where the code expects it to be as the tag
> is still present. Adding this new callback allows a DSA device to provide a
> new function that the flow_dissector can use to get the correct protocol
> and offset of the network header.
>
> Signed-off-by: Muciri Gatimu <muciri-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli-lv6y7wLVQPlWk0Htik3J/w@public.gmane.org>
> Signed-off-by: John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
Reviewed-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
Andrew
^ permalink raw reply
* Re: [PATCH 3/4] net-next: tag_mtk: add flow_dissect callback to the ops struct
From: Andrew Lunn @ 2017-08-09 13:54 UTC (permalink / raw)
To: John Crispin
Cc: Vivien Didelot, Florian Fainelli, David S . Miller, Sean Wang,
netdev, linux-mediatek, linux-kernel, Muciri Gatimu,
Shashidhar Lakkavalli
In-Reply-To: <20170809124119.24320-4-john@phrozen.org>
On Wed, Aug 09, 2017 at 02:41:18PM +0200, John Crispin wrote:
> The MT7530 inserts the 4 magic header in between the 802.3 address and
> protocol field. The patch implements the callback that can be called by
> the flow dissector to figure out the real protocol and offset of the
> network header. With this patch applied we can properly parse the packet
> and thus make hashing function properly.
>
> Signed-off-by: Muciri Gatimu <muciri@openmesh.com>
> Signed-off-by: Shashidhar Lakkavalli <shashidhar.lakkavalli@openmesh.com>
> Signed-off-by: John Crispin <john@phrozen.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
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