[PATCH v1 2/4] j1939: socket: SO_J1939_FILTER: optimize filter handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux