]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
Swapped the parameters inside the modifier attribute to have the aligned
authorhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Fri, 19 Feb 2010 05:12:49 +0000 (05:12 +0000)
committerhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Fri, 19 Feb 2010 05:12:49 +0000 (05:12 +0000)
struct can_frame the first parameter. This allows the usage of 'packed'
structs in userspace with an aligned access to the CAN frame structures.

git-svn-id: svn://svn.berlios.de//socketcan/trunk@1129 030b6a49-0b11-0410-94ab-b0dab22257f2

kernel/2.6/include/socketcan/can/gw.h
kernel/2.6/net/can/gw.c
test/gwtest.c

index 20feea302858009b01c660d1ffb30c69c937855b..b0dba41b008268e40c43857d9a4e2e99d5d4e5f5 100644 (file)
@@ -65,8 +65,8 @@ enum {
  * Specifies a modification that's done to a received CAN frame before it is
  * send out to the destination interface.
  *
- * <u8> affected CAN frame elements
  * <struct can_frame> data used as operator
+ * <u8> affected CAN frame elements
  *
  * Remark: The attribute data is a linear buffer. Beware of sending structs!
  */
index dafd0790d7d4d6f969a424a38107feeb5df67dab..262934bfcb23934ee4969d0e713e3f78cec1036e 100644 (file)
@@ -334,16 +334,16 @@ static int gw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
            nla_len(tb[CGW_MOD_AND]) == CGW_MODATTR_LEN) {
                nla_memcpy(&buf, tb[CGW_MOD_AND], CGW_MODATTR_LEN);
 
-               memcpy(&gwj->ccgw.modframe.and, &buf[1],
+               memcpy(&gwj->ccgw.modframe.and, buf,
                       sizeof(struct can_frame));
 
-               if (buf[0] & CGW_MOD_ID)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_ID)
                        gwj->ccgw.modfunc[modidx++] = mod_and_id;
 
-               if (buf[0] & CGW_MOD_DLC)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DLC)
                        gwj->ccgw.modfunc[modidx++] = mod_and_dlc;
 
-               if (buf[0] & CGW_MOD_DATA)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DATA)
                        gwj->ccgw.modfunc[modidx++] = mod_and_data;
        }
 
@@ -351,16 +351,16 @@ static int gw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
            nla_len(tb[CGW_MOD_OR]) == CGW_MODATTR_LEN) {
                nla_memcpy(&buf, tb[CGW_MOD_OR], CGW_MODATTR_LEN);
 
-               memcpy(&gwj->ccgw.modframe.or, &buf[1],
+               memcpy(&gwj->ccgw.modframe.or, buf,
                       sizeof(struct can_frame));
 
-               if (buf[0] & CGW_MOD_ID)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_ID)
                        gwj->ccgw.modfunc[modidx++] = mod_or_id;
 
-               if (buf[0] & CGW_MOD_DLC)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DLC)
                        gwj->ccgw.modfunc[modidx++] = mod_or_dlc;
 
-               if (buf[0] & CGW_MOD_DATA)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DATA)
                        gwj->ccgw.modfunc[modidx++] = mod_or_data;
        }
 
@@ -368,16 +368,16 @@ static int gw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
            nla_len(tb[CGW_MOD_XOR]) == CGW_MODATTR_LEN) {
                nla_memcpy(&buf, tb[CGW_MOD_XOR], CGW_MODATTR_LEN);
 
-               memcpy(&gwj->ccgw.modframe.xor, &buf[1],
+               memcpy(&gwj->ccgw.modframe.xor, buf,
                       sizeof(struct can_frame));
 
-               if (buf[0] & CGW_MOD_ID)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_ID)
                        gwj->ccgw.modfunc[modidx++] = mod_xor_id;
 
-               if (buf[0] & CGW_MOD_DLC)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DLC)
                        gwj->ccgw.modfunc[modidx++] = mod_xor_dlc;
 
-               if (buf[0] & CGW_MOD_DATA)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DATA)
                        gwj->ccgw.modfunc[modidx++] = mod_xor_data;
        }
 
@@ -385,16 +385,16 @@ static int gw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
            nla_len(tb[CGW_MOD_SET]) == CGW_MODATTR_LEN) {
                nla_memcpy(&buf, tb[CGW_MOD_SET], CGW_MODATTR_LEN);
 
-               memcpy(&gwj->ccgw.modframe.set, &buf[1],
+               memcpy(&gwj->ccgw.modframe.set, buf,
                       sizeof(struct can_frame));
 
-               if (buf[0] & CGW_MOD_ID)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_ID)
                        gwj->ccgw.modfunc[modidx++] = mod_set_id;
 
-               if (buf[0] & CGW_MOD_DLC)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DLC)
                        gwj->ccgw.modfunc[modidx++] = mod_set_dlc;
 
-               if (buf[0] & CGW_MOD_DATA)
+               if (buf[sizeof(struct can_frame)] & CGW_MOD_DATA)
                        gwj->ccgw.modfunc[modidx++] = mod_set_data;
        }
 
index 283d420a9841e256e97ebad3ffe4d06ebdb86b81..4aeb871935d32e585a8cc34dcc03df5a4535da16 100644 (file)
@@ -44,6 +44,8 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
        return 0;
 }
 
+#define USE_PACKED_STRUCT
+
 int main(int argc, char **argv)
 {
        int s;
@@ -56,10 +58,20 @@ int main(int argc, char **argv)
 
        } req;
 
-       static struct can_frame modframe;
        struct can_filter filter;
        struct sockaddr_nl nladdr;
+
+#ifdef USE_PACKED_STRUCT
+       struct modattr {
+               struct can_frame cf;
+               __u8 modtype;
+       } __attribute__((packed));
+
+       struct modattr modmsg;
+#else
+       static struct can_frame modframe;
        char modbuf[CGW_MODATTR_LEN];
+#endif
 
        s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
 
@@ -81,25 +93,45 @@ int main(int argc, char **argv)
        filter.can_mask = 0x700;
 
        addattr_l(&req.n, sizeof(req), CGW_FILTER, &filter, sizeof(filter));
+
+#ifdef USE_PACKED_STRUCT
+
+       if (sizeof(modmsg) != CGW_MODATTR_LEN) {
+               printf("Problem with packed msg. Use linear copy instead.\n");
+               return 1;
+       }
+
+       modmsg.cf.can_id  = 0x555;
+       modmsg.cf.can_dlc = 5;
+       *(unsigned long long *)modmsg.cf.data = 0x5555555555555555ULL;
+
+       modmsg.modtype = CGW_MOD_ID;
+       addattr_l(&req.n, sizeof(req), CGW_MOD_SET, &modmsg, CGW_MODATTR_LEN);
+
+       modmsg.modtype = CGW_MOD_DLC;
+       addattr_l(&req.n, sizeof(req), CGW_MOD_AND, &modmsg, CGW_MODATTR_LEN);
+
+       modmsg.modtype = CGW_MOD_DATA;
+       addattr_l(&req.n, sizeof(req), CGW_MOD_XOR, &modmsg, CGW_MODATTR_LEN);
+
+#else
+
        modframe.can_id  = 0x555;
        modframe.can_dlc = 5;
        *(unsigned long long *)modframe.data = 0x5555555555555555ULL;
 
-       modbuf[0] = CGW_MOD_ID;
-       memcpy(&modbuf[1], &modframe, sizeof(struct can_frame));
+       memcpy(modbuf, &modframe, sizeof(struct can_frame));
 
+       modbuf[sizeof(struct can_frame)] = CGW_MOD_ID;
        addattr_l(&req.n, sizeof(req), CGW_MOD_SET, modbuf, CGW_MODATTR_LEN);
 
-       modbuf[0] = CGW_MOD_DLC;
-       memcpy(&modbuf[1], &modframe, sizeof(struct can_frame));
-
+       modbuf[sizeof(struct can_frame)] = CGW_MOD_DLC;
        addattr_l(&req.n, sizeof(req), CGW_MOD_AND, modbuf, CGW_MODATTR_LEN);
 
-       modbuf[0] = CGW_MOD_DATA;
-       memcpy(&modbuf[1], &modframe, sizeof(struct can_frame));
-
+       modbuf[sizeof(struct can_frame)] = CGW_MOD_DATA;
        addattr_l(&req.n, sizeof(req), CGW_MOD_XOR, modbuf, CGW_MODATTR_LEN);
 
+#endif
 
        memset(&nladdr, 0, sizeof(nladdr));
        nladdr.nl_family = AF_NETLINK;