diff mbox series

[net-next,1/2] flow_dissector: Parse multiple MPLS Label Stack Entries

Message ID 1cf89ed887eff6121d344cd1c4e0e23d84c1ac33.1589993550.git.gnault@redhat.com
State Changes Requested
Delegated to: David Miller
Headers show
Series flow_dissector, cls_flower: Add support for multiple MPLS Label Stack Entries | expand

Commit Message

Guillaume Nault May 20, 2020, 5:28 p.m. UTC
The current MPLS dissector only parses the first MPLS Label Stack
Entry (second LSE can be parsed too, but only to set a key_id).

This patch adds the possibility to parse several LSEs by making
__skb_flow_dissect_mpls() return FLOW_DISSECT_RET_PROTO_AGAIN as long
as the Bottom Of Stack bit hasn't been seen, up to a maximum of
FLOW_DIS_MPLS_MAX entries.

FLOW_DIS_MPLS_MAX is arbitrarily set to 7. This should be enough for
many practical purposes, without wasting too much space.

To record the parsed values, flow_dissector_key_mpls is modified to
store an array of stack entries, instead of just the values of the
first one. A bit field, "used_lses", is also added to keep track of
the LSEs that have been set. The objective is to avoid defining a
new FLOW_DISSECTOR_KEY_MPLS_XX for each level of the MPLS stack.

TC flower, which is the only user of FLOW_DISSECTOR_KEY_MPLS, is
adapted for the new struct flow_dissector_key_mpls layout. Matching
on several MPLS Label Stack Entries will be added in the next patch.

Finally, the behaviour of the FLOW_DISSECTOR_KEY_MPLS_ENTROPY key is
slightly modified. Instead of recording the first Entropy Label, it
now records the last one. This shouldn't have any consequences since
there doesn't seem to have any user of FLOW_DISSECTOR_KEY_MPLS_ENTROPY
in the tree. We'd probably better do a hash of all parsed MPLS labels
instead (excluding reserved labels) anyway. That'd give better entropy
and would probably also simplify the code. But that's not the purpose
of this patch, so I'm keeping that as a future exercise.

Signed-off-by: Guillaume Nault <gnault@redhat.com>
---
 include/net/flow_dissector.h | 14 +++++++++-
 net/core/flow_dissector.c    | 49 ++++++++++++++++++++++-----------
 net/sched/cls_flower.c       | 52 +++++++++++++++++++++++++-----------
 3 files changed, 82 insertions(+), 33 deletions(-)

Comments

kernel test robot May 21, 2020, 1:24 a.m. UTC | #1
Hi Guillaume,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]
[also build test ERROR on net/master sparc-next/master linus/master v5.7-rc6 next-20200519]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Guillaume-Nault/flow_dissector-cls_flower-Add-support-for-multiple-MPLS-Label-Stack-Entries/20200521-052254
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 4f65e2f483b6f764c15094d14dd53dda048a4048
config: alpha-allyesconfig (attached as .config)
compiler: alpha-linux-gcc (GCC) 9.3.0
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
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=alpha 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c: In function 'nfp_flower_compile_mac':
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
100 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
|                                                         ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:100:12: note: in expansion of macro 'FIELD_PREP'
100 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
|            ^~~~~~~~~~
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
100 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
|                                                         ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:100:12: note: in expansion of macro 'FIELD_PREP'
100 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
|            ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
100 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
|                                                         ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 |   ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);          |                    ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:101:50: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
101 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
|                                                  ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:101:5: note: in expansion of macro 'FIELD_PREP'
101 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
|     ^~~~~~~~~~
>> drivers/net/ethernet/netronome/nfp/flower/match.c:101:50: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
101 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
|                                                  ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:101:5: note: in expansion of macro 'FIELD_PREP'
101 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
|     ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:101:50: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
101 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
|                                                  ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 |   ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);          |                    ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:102:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_bos'
102 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
|                                                   ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:102:5: note: in expansion of macro 'FIELD_PREP'
102 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
|     ^~~~~~~~~~
>> drivers/net/ethernet/netronome/nfp/flower/match.c:102:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_bos'
102 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
|                                                   ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:102:5: note: in expansion of macro 'FIELD_PREP'
102 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
|     ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
>> drivers/net/ethernet/netronome/nfp/flower/match.c:102:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_bos'
102 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
|                                                   ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 |   ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);          |                    ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c:105:58: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
105 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
|                                                          ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:105:12: note: in expansion of macro 'FIELD_PREP'
105 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
|            ^~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:105:58: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
105 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
|                                                          ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:105:12: note: in expansion of macro 'FIELD_PREP'
105 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
|            ^~~~~~~~~~
In file included from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c:105:58: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
105 |   t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
|                                                          ^~
include/linux/bitfield.h:95:20: note: in definition of macro 'FIELD_PREP'
95 |   ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);          |                    ^~~~
In file included from include/linux/build_bug.h:5,
from include/linux/bitfield.h:10,
from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
drivers/net/ethernet/netronome/nfp/flower/match.c:106:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
106 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
|                                                   ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:106:5: note: in expansion of macro 'FIELD_PREP'
106 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
|     ^~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:106:51: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_tc'
106 |     FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
|                                                   ^~
include/linux/compiler.h:330:9: note: in definition of macro '__compiletime_assert'
330 |   if (!(condition))              |         ^~~~~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
350 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|                                     ^~~~~~~~~~~~~~~~~~
include/linux/bitfield.h:49:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
49 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           |   ^~~~~~~~~~~~~~~~
include/linux/bitfield.h:94:3: note: in expansion of macro '__BF_FIELD_CHECK'
94 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");          |   ^~~~~~~~~~~~~~~~
drivers/net/ethernet/netronome/nfp/flower/match.c:106:5: note: in expansion of macro 'FIELD_PREP'

vim +100 drivers/net/ethernet/netronome/nfp/flower/match.c

5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29   76  
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29   77  static void
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   78  nfp_flower_compile_mac(struct nfp_flower_mac_mpls *ext,
31c491e56ad1ad John Hurley              2019-12-17   79  		       struct nfp_flower_mac_mpls *msk, struct flow_rule *rule)
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29   80  {
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   81  	memset(ext, 0, sizeof(struct nfp_flower_mac_mpls));
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   82  	memset(msk, 0, sizeof(struct nfp_flower_mac_mpls));
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29   83  
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   84  	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   85  		struct flow_match_eth_addrs match;
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29   86  
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   87  		flow_rule_match_eth_addrs(rule, &match);
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29   88  		/* Populate mac frame. */
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   89  		ether_addr_copy(ext->mac_dst, &match.key->dst[0]);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   90  		ether_addr_copy(ext->mac_src, &match.key->src[0]);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   91  		ether_addr_copy(msk->mac_dst, &match.mask->dst[0]);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   92  		ether_addr_copy(msk->mac_src, &match.mask->src[0]);
a7cd39e0c7805a Pieter Jansen van Vuuren 2017-08-25   93  	}
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29   94  
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   95  	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) {
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   96  		struct flow_match_mpls match;
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06   97  		u32 t_mpls;
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06   98  
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02   99  		flow_rule_match_mpls(rule, &match);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02 @100  		t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02 @101  			 FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02 @102  			 FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06  103  			 NFP_FLOWER_MASK_MPLS_Q;
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  104  		ext->mpls_lse = cpu_to_be32(t_mpls);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  105  		t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  106  			 FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  107  			 FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.mask->mpls_bos) |
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  108  			 NFP_FLOWER_MASK_MPLS_Q;
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  109  		msk->mpls_lse = cpu_to_be32(t_mpls);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  110  	} else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25  111  		/* Check for mpls ether type and set NFP_FLOWER_MASK_MPLS_Q
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25  112  		 * bit, which indicates an mpls ether type but without any
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25  113  		 * mpls fields.
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25  114  		 */
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  115  		struct flow_match_basic match;
a64119415ff248 Pieter Jansen van Vuuren 2018-06-25  116  
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  117  		flow_rule_match_basic(rule, &match);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  118  		if (match.key->n_proto == cpu_to_be16(ETH_P_MPLS_UC) ||
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  119  		    match.key->n_proto == cpu_to_be16(ETH_P_MPLS_MC)) {
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  120  			ext->mpls_lse = cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  121  			msk->mpls_lse = cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
8f2566225ae2d6 Pablo Neira Ayuso        2019-02-02  122  		}
bb055c198d9b2b Pieter Jansen van Vuuren 2017-10-06  123  	}
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29  124  }
5571e8c9f2419c Pieter Jansen van Vuuren 2017-06-29  125  

:::::: The code at line 100 was first introduced by commit
:::::: 8f2566225ae2d62d532bb1810ed74fa4bbc5bbdb flow_offload: add flow_rule and flow_match structures and use them

:::::: TO: Pablo Neira Ayuso <pablo@netfilter.org>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Guillaume Nault May 21, 2020, 10:09 a.m. UTC | #2
On Thu, May 21, 2020 at 09:24:25AM +0800, kbuild test robot wrote:
> All errors (new ones prefixed by >>, old ones prefixed by <<):
> 
> In file included from include/linux/build_bug.h:5,
> from include/linux/bitfield.h:10,
> from drivers/net/ethernet/netronome/nfp/flower/match.c:4:
> drivers/net/ethernet/netronome/nfp/flower/match.c: In function 'nfp_flower_compile_mac':
> >> drivers/net/ethernet/netronome/nfp/flower/match.c:100:57: error: 'struct flow_dissector_key_mpls' has no member named 'mpls_label'
> 
Sorry, I didn't realise this was used by NFP.
I'll respin.
kernel test robot May 21, 2020, 11:54 a.m. UTC | #3
Hi Guillaume,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]
[also build test WARNING on net/master sparc-next/master linus/master v5.7-rc6 next-20200519]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Guillaume-Nault/flow_dissector-cls_flower-Add-support-for-multiple-MPLS-Label-Stack-Entries/20200521-052254
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 4f65e2f483b6f764c15094d14dd53dda048a4048
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-193-gb8fad4bc-dirty
        # save the attached .config to linux build tree
        make C=1 ARCH=i386 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)

   drivers/net/ethernet/netronome/nfp/flower/match.c:100:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:100:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:26: sparse: sparse: cast from unknown type
   drivers/net/ethernet/netronome/nfp/flower/match.c:101:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:101:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:101:26: sparse: sparse: cast from unknown type
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:85: sparse: sparse: incompatible types for operation (|):
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:85: sparse:    void
>> drivers/net/ethernet/netronome/nfp/flower/match.c:100:85: sparse:    void
   drivers/net/ethernet/netronome/nfp/flower/match.c:102:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:102:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:102:26: sparse: sparse: cast from unknown type
   drivers/net/ethernet/netronome/nfp/flower/match.c:105:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:105:26: sparse: sparse: no member 'mpls_label' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:105:26: sparse: sparse: cast from unknown type
   drivers/net/ethernet/netronome/nfp/flower/match.c:106:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:106:26: sparse: sparse: no member 'mpls_tc' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:106:26: sparse: sparse: cast from unknown type
   drivers/net/ethernet/netronome/nfp/flower/match.c:105:86: sparse: sparse: incompatible types for operation (|):
   drivers/net/ethernet/netronome/nfp/flower/match.c:105:86: sparse:    void
   drivers/net/ethernet/netronome/nfp/flower/match.c:105:86: sparse:    void
   drivers/net/ethernet/netronome/nfp/flower/match.c:107:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:107:26: sparse: sparse: no member 'mpls_bos' in struct flow_dissector_key_mpls
   drivers/net/ethernet/netronome/nfp/flower/match.c:107:26: sparse: sparse: cast from unknown type
--
   net/core/flow_dissector.c:256:43: sparse: sparse: restricted __be16 degrades to integer
>> net/core/flow_dissector.c:514:34: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be32 [usertype] keyid @@    got unsignrestricted __be32 [usertype] keyid @@
>> net/core/flow_dissector.c:514:34: sparse:    expected restricted __be32 [usertype] keyid
>> net/core/flow_dissector.c:514:34: sparse:    got unsigned int [assigned] [usertype] label

vim +514 net/core/flow_dissector.c

   463	
   464	static enum flow_dissect_ret
   465	__skb_flow_dissect_mpls(const struct sk_buff *skb,
   466				struct flow_dissector *flow_dissector,
   467				void *target_container, void *data, int nhoff, int hlen,
   468				int lse_index, bool *entropy_label)
   469	{
   470		struct mpls_label *hdr, _hdr;
   471		u32 entry, label, bos;
   472	
   473		if (!dissector_uses_key(flow_dissector,
   474					FLOW_DISSECTOR_KEY_MPLS_ENTROPY) &&
   475		    !dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS))
   476			return FLOW_DISSECT_RET_OUT_GOOD;
   477	
   478		if (lse_index >= FLOW_DIS_MPLS_MAX)
   479			return FLOW_DISSECT_RET_OUT_GOOD;
   480	
   481		hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data,
   482					   hlen, &_hdr);
   483		if (!hdr)
   484			return FLOW_DISSECT_RET_OUT_BAD;
   485	
   486		entry = ntohl(hdr->entry);
   487		label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
   488		bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT;
   489	
   490		if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS)) {
   491			struct flow_dissector_key_mpls *key_mpls;
   492			struct flow_dissector_mpls_lse *lse;
   493	
   494			key_mpls = skb_flow_dissector_target(flow_dissector,
   495							     FLOW_DISSECTOR_KEY_MPLS,
   496							     target_container);
   497			lse = &key_mpls->ls[lse_index];
   498	
   499			lse->mpls_ttl = (entry & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT;
   500			lse->mpls_bos = bos;
   501			lse->mpls_tc = (entry & MPLS_LS_TC_MASK) >> MPLS_LS_TC_SHIFT;
   502			lse->mpls_label = label;
   503			dissector_set_mpls_lse(key_mpls, lse_index);
   504		}
   505	
   506		if (*entropy_label &&
   507		    dissector_uses_key(flow_dissector,
   508				       FLOW_DISSECTOR_KEY_MPLS_ENTROPY)) {
   509			struct flow_dissector_key_keyid *key_keyid;
   510	
   511			key_keyid = skb_flow_dissector_target(flow_dissector,
   512							      FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
   513							      target_container);
 > 514			key_keyid->keyid = label;
   515		}
   516	
   517		*entropy_label = label == MPLS_LABEL_ENTROPY;
   518	
   519		return bos ? FLOW_DISSECT_RET_OUT_GOOD : FLOW_DISSECT_RET_PROTO_AGAIN;
   520	}
   521	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index 628383915827..4fb1a69c6ecf 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -59,13 +59,25 @@  struct flow_dissector_key_vlan {
 	__be16	vlan_tpid;
 };
 
-struct flow_dissector_key_mpls {
+struct flow_dissector_mpls_lse {
 	u32	mpls_ttl:8,
 		mpls_bos:1,
 		mpls_tc:3,
 		mpls_label:20;
 };
 
+#define FLOW_DIS_MPLS_MAX 7
+struct flow_dissector_key_mpls {
+	struct flow_dissector_mpls_lse ls[FLOW_DIS_MPLS_MAX]; /* Label Stack */
+	u8 used_lses; /* One bit set for each Label Stack Entry in use */
+};
+
+static inline void dissector_set_mpls_lse(struct flow_dissector_key_mpls *mpls,
+					  int lse_index)
+{
+	mpls->used_lses |= 1 << lse_index;
+}
+
 #define FLOW_DIS_TUN_OPTS_MAX 255
 /**
  * struct flow_dissector_key_enc_opts:
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 3eff84824c8b..214d08aa3439 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -464,47 +464,59 @@  EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
 static enum flow_dissect_ret
 __skb_flow_dissect_mpls(const struct sk_buff *skb,
 			struct flow_dissector *flow_dissector,
-			void *target_container, void *data, int nhoff, int hlen)
+			void *target_container, void *data, int nhoff, int hlen,
+			int lse_index, bool *entropy_label)
 {
-	struct flow_dissector_key_keyid *key_keyid;
-	struct mpls_label *hdr, _hdr[2];
-	u32 entry, label;
+	struct mpls_label *hdr, _hdr;
+	u32 entry, label, bos;
 
 	if (!dissector_uses_key(flow_dissector,
 				FLOW_DISSECTOR_KEY_MPLS_ENTROPY) &&
 	    !dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS))
 		return FLOW_DISSECT_RET_OUT_GOOD;
 
+	if (lse_index >= FLOW_DIS_MPLS_MAX)
+		return FLOW_DISSECT_RET_OUT_GOOD;
+
 	hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data,
 				   hlen, &_hdr);
 	if (!hdr)
 		return FLOW_DISSECT_RET_OUT_BAD;
 
-	entry = ntohl(hdr[0].entry);
+	entry = ntohl(hdr->entry);
 	label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
+	bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT;
 
 	if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS)) {
 		struct flow_dissector_key_mpls *key_mpls;
+		struct flow_dissector_mpls_lse *lse;
 
 		key_mpls = skb_flow_dissector_target(flow_dissector,
 						     FLOW_DISSECTOR_KEY_MPLS,
 						     target_container);
-		key_mpls->mpls_label = label;
-		key_mpls->mpls_ttl = (entry & MPLS_LS_TTL_MASK)
-					>> MPLS_LS_TTL_SHIFT;
-		key_mpls->mpls_tc = (entry & MPLS_LS_TC_MASK)
-					>> MPLS_LS_TC_SHIFT;
-		key_mpls->mpls_bos = (entry & MPLS_LS_S_MASK)
-					>> MPLS_LS_S_SHIFT;
+		lse = &key_mpls->ls[lse_index];
+
+		lse->mpls_ttl = (entry & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT;
+		lse->mpls_bos = bos;
+		lse->mpls_tc = (entry & MPLS_LS_TC_MASK) >> MPLS_LS_TC_SHIFT;
+		lse->mpls_label = label;
+		dissector_set_mpls_lse(key_mpls, lse_index);
 	}
 
-	if (label == MPLS_LABEL_ENTROPY) {
+	if (*entropy_label &&
+	    dissector_uses_key(flow_dissector,
+			       FLOW_DISSECTOR_KEY_MPLS_ENTROPY)) {
+		struct flow_dissector_key_keyid *key_keyid;
+
 		key_keyid = skb_flow_dissector_target(flow_dissector,
 						      FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
 						      target_container);
-		key_keyid->keyid = hdr[1].entry & htonl(MPLS_LS_LABEL_MASK);
+		key_keyid->keyid = label;
 	}
-	return FLOW_DISSECT_RET_OUT_GOOD;
+
+	*entropy_label = label == MPLS_LABEL_ENTROPY;
+
+	return bos ? FLOW_DISSECT_RET_OUT_GOOD : FLOW_DISSECT_RET_PROTO_AGAIN;
 }
 
 static enum flow_dissect_ret
@@ -963,6 +975,8 @@  bool __skb_flow_dissect(const struct net *net,
 	struct bpf_prog *attached = NULL;
 	enum flow_dissect_ret fdret;
 	enum flow_dissector_key_id dissector_vlan = FLOW_DISSECTOR_KEY_MAX;
+	bool mpls_el = false;
+	int mpls_lse = 0;
 	int num_hdrs = 0;
 	u8 ip_proto = 0;
 	bool ret;
@@ -1262,7 +1276,10 @@  bool __skb_flow_dissect(const struct net *net,
 	case htons(ETH_P_MPLS_MC):
 		fdret = __skb_flow_dissect_mpls(skb, flow_dissector,
 						target_container, data,
-						nhoff, hlen);
+						nhoff, hlen, mpls_lse,
+						&mpls_el);
+		nhoff += sizeof(struct mpls_label);
+		mpls_lse++;
 		break;
 	case htons(ETH_P_FCOE):
 		if ((hlen - nhoff) < FCOE_HEADER_LEN) {
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 0c574700da75..f524afe0b7f5 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -781,9 +781,17 @@  static int fl_set_key_mpls(struct nlattr **tb,
 			   struct flow_dissector_key_mpls *key_mask,
 			   struct netlink_ext_ack *extack)
 {
+	struct flow_dissector_mpls_lse *lse_mask;
+	struct flow_dissector_mpls_lse *lse_val;
+
+	lse_val = &key_val->ls[0];
+	lse_mask = &key_mask->ls[0];
+
 	if (tb[TCA_FLOWER_KEY_MPLS_TTL]) {
-		key_val->mpls_ttl = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TTL]);
-		key_mask->mpls_ttl = MPLS_TTL_MASK;
+		lse_val->mpls_ttl = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TTL]);
+		lse_mask->mpls_ttl = MPLS_TTL_MASK;
+		dissector_set_mpls_lse(key_val, 0);
+		dissector_set_mpls_lse(key_mask, 0);
 	}
 	if (tb[TCA_FLOWER_KEY_MPLS_BOS]) {
 		u8 bos = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_BOS]);
@@ -794,8 +802,10 @@  static int fl_set_key_mpls(struct nlattr **tb,
 					    "Bottom Of Stack (BOS) must be 0 or 1");
 			return -EINVAL;
 		}
-		key_val->mpls_bos = bos;
-		key_mask->mpls_bos = MPLS_BOS_MASK;
+		lse_val->mpls_bos = bos;
+		lse_mask->mpls_bos = MPLS_BOS_MASK;
+		dissector_set_mpls_lse(key_val, 0);
+		dissector_set_mpls_lse(key_mask, 0);
 	}
 	if (tb[TCA_FLOWER_KEY_MPLS_TC]) {
 		u8 tc = nla_get_u8(tb[TCA_FLOWER_KEY_MPLS_TC]);
@@ -806,8 +816,10 @@  static int fl_set_key_mpls(struct nlattr **tb,
 					    "Traffic Class (TC) must be between 0 and 7");
 			return -EINVAL;
 		}
-		key_val->mpls_tc = tc;
-		key_mask->mpls_tc = MPLS_TC_MASK;
+		lse_val->mpls_tc = tc;
+		lse_mask->mpls_tc = MPLS_TC_MASK;
+		dissector_set_mpls_lse(key_val, 0);
+		dissector_set_mpls_lse(key_mask, 0);
 	}
 	if (tb[TCA_FLOWER_KEY_MPLS_LABEL]) {
 		u32 label = nla_get_u32(tb[TCA_FLOWER_KEY_MPLS_LABEL]);
@@ -818,8 +830,10 @@  static int fl_set_key_mpls(struct nlattr **tb,
 					    "Label must be between 0 and 1048575");
 			return -EINVAL;
 		}
-		key_val->mpls_label = label;
-		key_mask->mpls_label = MPLS_LABEL_MASK;
+		lse_val->mpls_label = label;
+		lse_mask->mpls_label = MPLS_LABEL_MASK;
+		dissector_set_mpls_lse(key_val, 0);
+		dissector_set_mpls_lse(key_mask, 0);
 	}
 	return 0;
 }
@@ -2222,31 +2236,37 @@  static int fl_dump_key_mpls(struct sk_buff *skb,
 			    struct flow_dissector_key_mpls *mpls_key,
 			    struct flow_dissector_key_mpls *mpls_mask)
 {
+	struct flow_dissector_mpls_lse *lse_mask;
+	struct flow_dissector_mpls_lse *lse_key;
 	int err;
 
 	if (!memchr_inv(mpls_mask, 0, sizeof(*mpls_mask)))
 		return 0;
-	if (mpls_mask->mpls_ttl) {
+
+	lse_mask = &mpls_mask->ls[0];
+	lse_key = &mpls_key->ls[0];
+
+	if (lse_mask->mpls_ttl) {
 		err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_TTL,
-				 mpls_key->mpls_ttl);
+				 lse_key->mpls_ttl);
 		if (err)
 			return err;
 	}
-	if (mpls_mask->mpls_tc) {
+	if (lse_mask->mpls_tc) {
 		err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_TC,
-				 mpls_key->mpls_tc);
+				 lse_key->mpls_tc);
 		if (err)
 			return err;
 	}
-	if (mpls_mask->mpls_label) {
+	if (lse_mask->mpls_label) {
 		err = nla_put_u32(skb, TCA_FLOWER_KEY_MPLS_LABEL,
-				  mpls_key->mpls_label);
+				  lse_key->mpls_label);
 		if (err)
 			return err;
 	}
-	if (mpls_mask->mpls_bos) {
+	if (lse_mask->mpls_bos) {
 		err = nla_put_u8(skb, TCA_FLOWER_KEY_MPLS_BOS,
-				 mpls_key->mpls_bos);
+				 lse_key->mpls_bos);
 		if (err)
 			return err;
 	}