Replace the hand written BPF code with something that has been created
by tcpdump based on a filter rule. This has the advantage that it can be
extended/ modified based text syntax and is safer to extend in regard to
jump labels.
The generated asm/ BFP code is longer by one opcode because the "and"
operation from VLAN and non-VLAN comparison is not optimized/ merged as
it is the case in the hand-written code.
Also provide two structs/ filters which either filter for the generic or
event PTP packet instead of accessing the struct directly and changing
the jump opcode.

The result is less readable if it comes to offsets. If this is an issue
than it could be optimized with some kind of pre-processor.

Signed-off-by: Sebastian Andrzej Siewior <bige...@linutronix.de>
---
 contain.h |   2 ++
 ether.h   |   2 --
 raw.c     | 104 ++++++++++++++++++++++++++++++++++++++----------------
 3 files changed, 76 insertions(+), 32 deletions(-)

diff --git a/contain.h b/contain.h
index e0090bca7dffa..a611a9f640945 100644
--- a/contain.h
+++ b/contain.h
@@ -30,4 +30,6 @@
        (type *)( (char *)__mptr - offsetof(type, member) );    \
 })
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 #endif
diff --git a/ether.h b/ether.h
index 8ec96691468b6..276eec44997db 100644
--- a/ether.h
+++ b/ether.h
@@ -48,6 +48,4 @@ struct vlan_hdr {
        uint16_t type;
 } __attribute__((packed));
 
-#define OFF_ETYPE (2 * sizeof(eth_addr))
-
 #endif
diff --git a/raw.c b/raw.c
index b9abe7a4f7c96..a76fab67242d3 100644
--- a/raw.c
+++ b/raw.c
@@ -55,50 +55,94 @@ struct raw {
        int vlan;
 };
 
-#define OP_AND  (BPF_ALU | BPF_AND | BPF_K)
-#define OP_JEQ  (BPF_JMP | BPF_JEQ | BPF_K)
-#define OP_JUN  (BPF_JMP | BPF_JA)
-#define OP_LDB  (BPF_LD  | BPF_B   | BPF_ABS)
-#define OP_LDH  (BPF_LD  | BPF_H   | BPF_ABS)
-#define OP_RETK (BPF_RET | BPF_K)
-
 #define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type 
*/
 
-#define N_RAW_FILTER    12
-#define RAW_FILTER_TEST 9
-
 #define PRP_MIN_PACKET_LEN 70
 #define PRP_TRAILER_LEN 6
 
-static struct sock_filter raw_filter[N_RAW_FILTER] = {
-       {OP_LDH,  0, 0, OFF_ETYPE   },
-       {OP_JEQ,  0, 4, ETH_P_8021Q          }, /*f goto non-vlan block*/
-       {OP_LDH,  0, 0, OFF_ETYPE + 4        },
-       {OP_JEQ,  0, 7, ETH_P_1588           }, /*f goto reject*/
-       {OP_LDB,  0, 0, ETH_HLEN + VLAN_HLEN },
-       {OP_JUN,  0, 0, 2                    }, /*goto test general bit*/
-       {OP_JEQ,  0, 4, ETH_P_1588  }, /*f goto reject*/
-       {OP_LDB,  0, 0, ETH_HLEN    },
-       {OP_AND,  0, 0, PTP_GEN_BIT }, /*test general bit*/
-       {OP_JEQ,  0, 1, 0           }, /*0,1=accept event; 1,0=accept general*/
-       {OP_RETK, 0, 0, 1500        }, /*accept*/
-       {OP_RETK, 0, 0, 0           }, /*reject*/
+/*
+ * tcpdump -d \
+ * '   (ether[12:2] == 0x8100 and ether[12 + 4 :2] == 0x88F7 and ether[14+4 
:1] & 0x8 == 0x8) '\
+ * 'or (ether[12:2] == 0x88F7 and                                ether[14   
:1] & 0x8 == 0x8) '
+ *
+ * (000) ldh      [12]
+ * (001) jeq      #0x8100          jt 2    jf 7
+ * (002) ldh      [16]
+ * (003) jeq      #0x88f7          jt 4    jf 12
+ * (004) ldb      [18]
+ * (005) and      #0x8
+ * (006) jeq      #0x8             jt 11   jf 12
+ * (007) jeq      #0x88f7          jt 8    jf 12
+ * (008) ldb      [14]
+ * (009) and      #0x8
+ * (010) jeq      #0x8             jt 11   jf 12
+ * (011) ret      #262144
+ * (012) ret      #0
+*/
+static struct sock_filter raw_filter_vlan_norm_general[] = {
+       { 0x28, 0, 0, 0x0000000c },
+       { 0x15, 0, 5, 0x00008100 },
+       { 0x28, 0, 0, 0x00000010 },
+       { 0x15, 0, 8, 0x000088f7 },
+       { 0x30, 0, 0, 0x00000012 },
+       { 0x54, 0, 0, 0x00000008 },
+       { 0x15, 4, 5, 0x00000008 },
+       { 0x15, 0, 4, 0x000088f7 },
+       { 0x30, 0, 0, 0x0000000e },
+       { 0x54, 0, 0, 0x00000008 },
+       { 0x15, 0, 1, 0x00000008 },
+       { 0x6, 0, 0, 0x00040000 },
+       { 0x6, 0, 0, 0x00000000 },
+};
+
+/*
+ * tcpdump -d \
+ *  '   (ether[12:2] == 0x8100 and ether[12 + 4 :2] == 0x88F7 and ether[14+4 
:1] & 0x8 != 0x8) '\
+ *  'or (ether[12:2] == 0x88F7 and                                ether[14   
:1] & 0x8 != 0x8) '
+ *
+ * (000) ldh      [12]
+ * (001) jeq      #0x8100          jt 2    jf 7
+ * (002) ldh      [16]
+ * (003) jeq      #0x88f7          jt 4    jf 12
+ * (004) ldb      [18]
+ * (005) and      #0x8
+ * (006) jeq      #0x8             jt 12   jf 11
+ * (007) jeq      #0x88f7          jt 8    jf 12
+ * (008) ldb      [14]
+ * (009) and      #0x8
+ * (010) jeq      #0x8             jt 12   jf 11
+ * (011) ret      #262144
+ * (012) ret      #0
+ */
+static struct sock_filter raw_filter_vlan_norm_event[] = {
+       { 0x28, 0, 0, 0x0000000c },
+       { 0x15, 0, 5, 0x00008100 },
+       { 0x28, 0, 0, 0x00000010 },
+       { 0x15, 0, 8, 0x000088f7 },
+       { 0x30, 0, 0, 0x00000012 },
+       { 0x54, 0, 0, 0x00000008 },
+       { 0x15, 5, 4, 0x00000008 },
+       { 0x15, 0, 4, 0x000088f7 },
+       { 0x30, 0, 0, 0x0000000e },
+       { 0x54, 0, 0, 0x00000008 },
+       { 0x15, 1, 0, 0x00000008 },
+       { 0x6, 0, 0, 0x00040000 },
+       { 0x6, 0, 0, 0x00000000 },
 };
 
 static int raw_configure(int fd, int event, int index,
                         unsigned char *addr1, unsigned char *addr2, int enable)
 {
-       int err1, err2, filter_test, option;
+       int err1, err2, option;
        struct packet_mreq mreq;
-       struct sock_fprog prg = { N_RAW_FILTER, raw_filter };
+       struct sock_fprog prg;
 
-       filter_test = RAW_FILTER_TEST;
        if (event) {
-               raw_filter[filter_test].jt = 0;
-               raw_filter[filter_test].jf = 1;
+               prg.len = ARRAY_SIZE(raw_filter_vlan_norm_event);
+               prg.filter = raw_filter_vlan_norm_event;
        } else {
-               raw_filter[filter_test].jt = 1;
-               raw_filter[filter_test].jf = 0;
+               prg.len = ARRAY_SIZE(raw_filter_vlan_norm_general);
+               prg.filter = raw_filter_vlan_norm_general;
        }
 
        if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &prg, sizeof(prg))) {
-- 
2.39.0



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to