This patch is RFC and would be applied after "flow_dissector: Protocol specific flow dissector offload"
In order to maitain uAPI in flower, the FLOW_DISSECTOR_F_FLOWER flag is added to indicate to flow_dissector that the caller is flower. As new funtionality is addes to flow_dissector that would break the flower uAPI, the code can be wrapped in "if (!(flags & FLOW_DISSECTOR_F_FLOWER)). In this patch the conditional is use around protocol specific dissection (e.g. DPI into VXLAN) as well as the code that enforces a depth of parsing to prevent DPI. The latter was a recent patch that would introduce a parsing limit to flower that did not exist before (i.e. would break uAPI). Signed-off-by: Tom Herbert <t...@quantonium.net> --- include/net/flow_dissector.h | 1 + net/core/flow_dissector.c | 17 +++++++++++------ net/sched/cls_flow.c | 3 ++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index ad75bbfd1c9c..ca315107d147 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -214,6 +214,7 @@ enum flow_dissector_key_id { #define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(2) #define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(3) #define FLOW_DISSECTOR_F_STOP_AT_L4 BIT(4) +#define FLOW_DISSECTOR_F_FLOWER BIT(5) struct flow_dissector_key { enum flow_dissector_key_id key_id; diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 84b8eb1f6664..a4d5843ec34e 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -383,8 +383,11 @@ __skb_flow_dissect_ipv6(const struct sk_buff *skb, */ #define MAX_FLOW_DISSECT_HDRS 15 -static bool skb_flow_dissect_allowed(int *num_hdrs) +static bool skb_flow_dissect_allowed(int *num_hdrs, unsigned int flags) { + if (flags & FLOW_DISSECTOR_F_FLOWER) + return true; + ++*num_hdrs; return (*num_hdrs <= MAX_FLOW_DISSECT_HDRS); @@ -722,7 +725,8 @@ bool __skb_flow_dissect(struct sk_buff *skb, break; default: - fdret = flow_dissect_by_type(skb, proto, key_control, + if (!(flags & FLOW_DISSECTOR_F_FLOWER)) + fdret = flow_dissect_by_type(skb, proto, key_control, flow_dissector, target_container, data, &proto, &ip_proto, &nhoff, @@ -735,7 +739,7 @@ bool __skb_flow_dissect(struct sk_buff *skb, case FLOW_DISSECT_RET_OUT_GOOD: goto out_good; case FLOW_DISSECT_RET_PROTO_AGAIN: - if (skb_flow_dissect_allowed(&num_hdrs)) + if (skb_flow_dissect_allowed(&num_hdrs, flags)) goto proto_again; goto out_good; case FLOW_DISSECT_RET_CONTINUE: @@ -843,7 +847,8 @@ bool __skb_flow_dissect(struct sk_buff *skb, break; default: - fdret = flow_dissect_by_type_proto(skb, proto, + if (!(flags & FLOW_DISSECTOR_F_FLOWER)) + fdret = flow_dissect_by_type_proto(skb, proto, ip_proto, key_control, flow_dissector, target_container, @@ -872,11 +877,11 @@ bool __skb_flow_dissect(struct sk_buff *skb, /* Process result of IP proto processing */ switch (fdret) { case FLOW_DISSECT_RET_PROTO_AGAIN: - if (skb_flow_dissect_allowed(&num_hdrs)) + if (skb_flow_dissect_allowed(&num_hdrs, flags)) goto proto_again; break; case FLOW_DISSECT_RET_IPPROTO_AGAIN: - if (skb_flow_dissect_allowed(&num_hdrs)) + if (skb_flow_dissect_allowed(&num_hdrs, flags)) goto ip_proto_again; break; case FLOW_DISSECT_RET_OUT_GOOD: diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 2a3a60ec5b86..ad4ac503697e 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -315,7 +315,8 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp, keymask = f->keymask; if (keymask & FLOW_KEYS_NEEDED) - skb_flow_dissect_flow_keys(skb, &flow_keys, 0); + skb_flow_dissect_flow_keys(skb, &flow_keys, + FLOW_DISSECTOR_F_FLOWER); for (n = 0; n < f->nkeys; n++) { key = ffs(keymask) - 1; -- 2.11.0