Optimize the filter handling by proper aligning the struct j1939_filter and applying the mask ahead of time instead for every packet. Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> --- include/uapi/linux/can/j1939.h | 4 ++-- net/can/j1939/socket.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/can/j1939.h b/include/uapi/linux/can/j1939.h index dad7f9720388..0c76bd2caf90 100644 --- a/include/uapi/linux/can/j1939.h +++ b/include/uapi/linux/can/j1939.h @@ -76,10 +76,10 @@ enum { struct j1939_filter { name_t name; name_t name_mask; - __u8 addr; - __u8 addr_mask; pgn_t pgn; pgn_t pgn_mask; + __u8 addr; + __u8 addr_mask; }; #define J1939_FILTER_MAX 512 /* maximum number of j1939_filter set via setsockopt() */ diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c index 1205b6143d19..f212e8b19fc7 100644 --- a/net/can/j1939/socket.c +++ b/net/can/j1939/socket.c @@ -163,12 +163,11 @@ static bool j1939_sk_match_filter(struct j1939_sock *jsk, * Sockets using dynamic addressing in their filters should not set it. */ for (; nfilter; ++f, --nfilter) { - if ((skcb->addr.pgn & f->pgn_mask) != (f->pgn & f->pgn_mask)) + if ((skcb->addr.pgn & f->pgn_mask) != f->pgn) continue; - if ((skcb->addr.sa & f->addr_mask) != (f->addr & f->addr_mask)) + if ((skcb->addr.sa & f->addr_mask) != f->addr) continue; - if ((skcb->addr.src_name & f->name_mask) != - (f->name & f->name_mask)) + if ((skcb->addr.src_name & f->name_mask) != f->name) continue; return true; } @@ -500,6 +499,9 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname, switch (optname) { case SO_J1939_FILTER: if (optval) { + struct j1939_filter *f; + int c; + if (optlen % sizeof(*filters) != 0) return -EINVAL; @@ -511,6 +513,12 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname, filters = memdup_user(optval, optlen); if (IS_ERR(filters)) return PTR_ERR(filters); + + for (f = filters, c = count; c; f++, c--) { + f->name &= f->name_mask; + f->pgn &= f->pgn_mask; + f->addr &= f->addr_mask; + } } lock_sock(&jsk->sk); -- 2.20.1