History

can: gw: use struct canfd_frame as internal data structure

To prepare the CAN FD support this patch implements the first adaptions in data structures for CAN FD without changing the current functionality. Additionally some code at the end of this patch is moved or indented to simplify the review of the next implementation step.

Oliver Hartkopp committed 7 years ago

Commit e9dc7c61 parent 21468e62 files · +120 −107Browse files

Unified · Split

2 files
  1. include/uapi/linux/can/gw.h +3 −2
  2. net/can/gw.c +117 −105
include/uapi/linux/can/gw.h+3−2
@@ -93,10 +93,11 @@ enum { · 92 unmodified lines
93 93
94/* CAN frame elements that are affected by curr. 3 CAN frame modifications */94/* CAN frame elements that are affected by curr. 3 CAN frame modifications */
95#define CGW_MOD_ID 0x0195#define CGW_MOD_ID 0x01
96#define CGW_MOD_DLC 0x0296#define CGW_MOD_DLC 0x02 /* contains the data length in bytes */
97#define CGW_MOD_LEN CGW_MOD_DLC /* CAN FD length representation */
97#define CGW_MOD_DATA 0x0498#define CGW_MOD_DATA 0x04
98 99
99#define CGW_FRAME_MODS 3 /* ID DLC DATA */100#define CGW_FRAME_MODS 3 /* ID DLC/LEN DATA */
100 101
101#define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS)102#define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS)
102 103
net/can/gw.c+117−105
@@ -85,10 +85,10 @@ static struct kmem_cache *cgw_cache __read_mostly; · 84 unmodified lines
85/* structure that contains the (on-the-fly) CAN frame modifications */85/* structure that contains the (on-the-fly) CAN frame modifications */
86struct cf_mod {86struct cf_mod {
87 struct {87 struct {
88 struct can_frame and;88 struct canfd_frame and;
89 struct can_frame or;89 struct canfd_frame or;
90 struct can_frame xor;90 struct canfd_frame xor;
91 struct can_frame set;91 struct canfd_frame set;
92 } modframe;92 } modframe;
93 struct {93 struct {
94 u8 and;94 u8 and;
@@ -96,7 +96,7 @@ struct cf_mod { · 1 unmodified line
96 u8 xor;96 u8 xor;
97 u8 set;97 u8 set;
98 } modtype;98 } modtype;
99 void (*modfunc[MAX_MODFUNCTIONS])(struct can_frame *cf,99 void (*modfunc[MAX_MODFUNCTIONS])(struct canfd_frame *cf,
100 struct cf_mod *mod);100 struct cf_mod *mod);
101 101
102 /* CAN frame checksum calculation after CAN frame modifications */102 /* CAN frame checksum calculation after CAN frame modifications */
@@ -105,8 +105,10 @@ struct cf_mod { · 2 unmodified lines
105 struct cgw_csum_crc8 crc8;105 struct cgw_csum_crc8 crc8;
106 } csum;106 } csum;
107 struct {107 struct {
108 void (*xor)(struct can_frame *cf, struct cgw_csum_xor *xor);108 void (*xor)(struct canfd_frame *cf,
109 void (*crc8)(struct can_frame *cf, struct cgw_csum_crc8 *crc8);109 struct cgw_csum_xor *xor);
110 void (*crc8)(struct canfd_frame *cf,
111 struct cgw_csum_crc8 *crc8);
110 } csumfunc;112 } csumfunc;
111 u32 uid;113 u32 uid;
112};114};
@@ -149,23 +151,23 @@ struct cgw_job { · 36 unmodified lines
149 151
150/* modification functions that are invoked in the hot path in can_can_gw_rcv */152/* modification functions that are invoked in the hot path in can_can_gw_rcv */
151 153
152#define MODFUNC(func, op) static void func(struct can_frame *cf, \154#define MODFUNC(func, op) static void func(struct canfd_frame *cf, \
153 struct cf_mod *mod) { op ; }155 struct cf_mod *mod) { op ; }
154 156
155MODFUNC(mod_and_id, cf->can_id &= mod->modframe.and.can_id)157MODFUNC(mod_and_id, cf->can_id &= mod->modframe.and.can_id)
156MODFUNC(mod_and_dlc, cf->can_dlc &= mod->modframe.and.can_dlc)158MODFUNC(mod_and_len, cf->len &= mod->modframe.and.len)
157MODFUNC(mod_and_data, *(u64 *)cf->data &= *(u64 *)mod->modframe.and.data)159MODFUNC(mod_and_data, *(u64 *)cf->data &= *(u64 *)mod->modframe.and.data)
158MODFUNC(mod_or_id, cf->can_id |= mod->modframe.or.can_id)160MODFUNC(mod_or_id, cf->can_id |= mod->modframe.or.can_id)
159MODFUNC(mod_or_dlc, cf->can_dlc |= mod->modframe.or.can_dlc)161MODFUNC(mod_or_len, cf->len |= mod->modframe.or.len)
160MODFUNC(mod_or_data, *(u64 *)cf->data |= *(u64 *)mod->modframe.or.data)162MODFUNC(mod_or_data, *(u64 *)cf->data |= *(u64 *)mod->modframe.or.data)
161MODFUNC(mod_xor_id, cf->can_id ^= mod->modframe.xor.can_id)163MODFUNC(mod_xor_id, cf->can_id ^= mod->modframe.xor.can_id)
162MODFUNC(mod_xor_dlc, cf->can_dlc ^= mod->modframe.xor.can_dlc)164MODFUNC(mod_xor_len, cf->len ^= mod->modframe.xor.len)
163MODFUNC(mod_xor_data, *(u64 *)cf->data ^= *(u64 *)mod->modframe.xor.data)165MODFUNC(mod_xor_data, *(u64 *)cf->data ^= *(u64 *)mod->modframe.xor.data)
164MODFUNC(mod_set_id, cf->can_id = mod->modframe.set.can_id)166MODFUNC(mod_set_id, cf->can_id = mod->modframe.set.can_id)
165MODFUNC(mod_set_dlc, cf->can_dlc = mod->modframe.set.can_dlc)167MODFUNC(mod_set_len, cf->len = mod->modframe.set.len)
166MODFUNC(mod_set_data, *(u64 *)cf->data = *(u64 *)mod->modframe.set.data)168MODFUNC(mod_set_data, *(u64 *)cf->data = *(u64 *)mod->modframe.set.data)
167 169
168static inline void canframecpy(struct can_frame *dst, struct can_frame *src)170static void canframecpy(struct canfd_frame *dst, struct can_frame *src)
169{171{
170 /* Copy the struct members separately to ensure that no uninitialized172 /* Copy the struct members separately to ensure that no uninitialized
171 * data are copied in the 3 bytes hole of the struct. This is needed173 * data are copied in the 3 bytes hole of the struct. This is needed
@@ -173,12 +175,14 @@ static inline void canframecpy(struct can_frame *dst, struct can_frame *src) · 1 unmodified line
173 */175 */
174 176
175 dst->can_id = src->can_id;177 dst->can_id = src->can_id;
176 dst->can_dlc = src->can_dlc;178 dst->len = src->can_dlc;
177 *(u64 *)dst->data = *(u64 *)src->data;179 *(u64 *)dst->data = *(u64 *)src->data;
178}180}
179 181
180static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re)182static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re)
181{183{
184 s8 dlen = CAN_MAX_DLEN;
185
182 /* absolute dlc values 0 .. 7 => 0 .. 7, e.g. data [0]186 /* absolute dlc values 0 .. 7 => 0 .. 7, e.g. data [0]
183 * relative to received dlc -1 .. -8 :187 * relative to received dlc -1 .. -8 :
184 * e.g. for received dlc = 8188 * e.g. for received dlc = 8
@@ -187,27 +191,27 @@ static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re) · 2 unmodified lines
187 * -8 => index = 0 (data[0])191 * -8 => index = 0 (data[0])
188 */192 */
189 193
190 if (fr > -9 && fr < 8 &&194 if (fr >= -dlen && fr < dlen &&
191 to > -9 && to < 8 &&195 to >= -dlen && to < dlen &&
192 re > -9 && re < 8)196 re >= -dlen && re < dlen)
193 return 0;197 return 0;
194 else198 else
195 return -EINVAL;199 return -EINVAL;
196}200}
197 201
198static inline int calc_idx(int idx, int rx_dlc)202static inline int calc_idx(int idx, int rx_len)
199{203{
200 if (idx < 0)204 if (idx < 0)
201 return rx_dlc + idx;205 return rx_len + idx;
202 else206 else
203 return idx;207 return idx;
204}208}
205 209
206static void cgw_csum_xor_rel(struct can_frame *cf, struct cgw_csum_xor *xor)210static void cgw_csum_xor_rel(struct canfd_frame *cf, struct cgw_csum_xor *xor)
207{211{
208 int from = calc_idx(xor->from_idx, cf->can_dlc);212 int from = calc_idx(xor->from_idx, cf->len);
209 int to = calc_idx(xor->to_idx, cf->can_dlc);213 int to = calc_idx(xor->to_idx, cf->len);
210 int res = calc_idx(xor->result_idx, cf->can_dlc);214 int res = calc_idx(xor->result_idx, cf->len);
211 u8 val = xor->init_xor_val;215 u8 val = xor->init_xor_val;
212 int i;216 int i;
213 217
@@ -225,7 +229,7 @@ static void cgw_csum_xor_rel(struct can_frame *cf, struct cgw_csum_xor *xor) · 11 unmodified lines
225 cf->data[res] = val;229 cf->data[res] = val;
226}230}
227 231
228static void cgw_csum_xor_pos(struct can_frame *cf, struct cgw_csum_xor *xor)232static void cgw_csum_xor_pos(struct canfd_frame *cf, struct cgw_csum_xor *xor)
229{233{
230 u8 val = xor->init_xor_val;234 u8 val = xor->init_xor_val;
231 int i;235 int i;
@@ -236,7 +240,7 @@ static void cgw_csum_xor_pos(struct can_frame *cf, struct cgw_csum_xor *xor) · 4 unmodified lines
236 cf->data[xor->result_idx] = val;240 cf->data[xor->result_idx] = val;
237}241}
238 242
239static void cgw_csum_xor_neg(struct can_frame *cf, struct cgw_csum_xor *xor)243static void cgw_csum_xor_neg(struct canfd_frame *cf, struct cgw_csum_xor *xor)
240{244{
241 u8 val = xor->init_xor_val;245 u8 val = xor->init_xor_val;
242 int i;246 int i;
@@ -247,11 +251,12 @@ static void cgw_csum_xor_neg(struct can_frame *cf, struct cgw_csum_xor *xor) · 4 unmodified lines
247 cf->data[xor->result_idx] = val;251 cf->data[xor->result_idx] = val;
248}252}
249 253
250static void cgw_csum_crc8_rel(struct can_frame *cf, struct cgw_csum_crc8 *crc8)254static void cgw_csum_crc8_rel(struct canfd_frame *cf,
255 struct cgw_csum_crc8 *crc8)
251{256{
252 int from = calc_idx(crc8->from_idx, cf->can_dlc);257 int from = calc_idx(crc8->from_idx, cf->len);
253 int to = calc_idx(crc8->to_idx, cf->can_dlc);258 int to = calc_idx(crc8->to_idx, cf->len);
254 int res = calc_idx(crc8->result_idx, cf->can_dlc);259 int res = calc_idx(crc8->result_idx, cf->len);
255 u8 crc = crc8->init_crc_val;260 u8 crc = crc8->init_crc_val;
256 int i;261 int i;
257 262
@@ -284,7 +289,8 @@ static void cgw_csum_crc8_rel(struct can_frame *cf, struct cgw_csum_crc8 *crc8) · 26 unmodified lines
284 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;289 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;
285}290}
286 291
287static void cgw_csum_crc8_pos(struct can_frame *cf, struct cgw_csum_crc8 *crc8)292static void cgw_csum_crc8_pos(struct canfd_frame *cf,
293 struct cgw_csum_crc8 *crc8)
288{294{
289 u8 crc = crc8->init_crc_val;295 u8 crc = crc8->init_crc_val;
290 int i;296 int i;
@@ -310,7 +316,8 @@ static void cgw_csum_crc8_pos(struct can_frame *cf, struct cgw_csum_crc8 *crc8) · 19 unmodified lines
310 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;316 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;
311}317}
312 318
313static void cgw_csum_crc8_neg(struct can_frame *cf, struct cgw_csum_crc8 *crc8)319static void cgw_csum_crc8_neg(struct canfd_frame *cf,
320 struct cgw_csum_crc8 *crc8)
314{321{
315 u8 crc = crc8->init_crc_val;322 u8 crc = crc8->init_crc_val;
316 int i;323 int i;
@@ -340,7 +347,7 @@ static void cgw_csum_crc8_neg(struct can_frame *cf, struct cgw_csum_crc8 *crc8) · 23 unmodified lines
340static void can_can_gw_rcv(struct sk_buff *skb, void *data)347static void can_can_gw_rcv(struct sk_buff *skb, void *data)
341{348{
342 struct cgw_job *gwj = (struct cgw_job *)data;349 struct cgw_job *gwj = (struct cgw_job *)data;
343 struct can_frame *cf;350 struct canfd_frame *cf;
344 struct sk_buff *nskb;351 struct sk_buff *nskb;
345 int modidx = 0;352 int modidx = 0;
346 353
@@ -400,7 +407,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) · 53 unmodified lines
400 nskb->dev = gwj->dst.dev;407 nskb->dev = gwj->dst.dev;
401 408
402 /* pointer to modifiable CAN frame */409 /* pointer to modifiable CAN frame */
403 cf = (struct can_frame *)nskb->data;410 cf = (struct canfd_frame *)nskb->data;
404 411
405 /* perform preprocessed modification functions if there are any */412 /* perform preprocessed modification functions if there are any */
406 while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx])413 while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx])
@@ -409,22 +416,22 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) · 2 unmodified lines
409 /* Has the CAN frame been modified? */416 /* Has the CAN frame been modified? */
410 if (modidx) {417 if (modidx) {
411 /* get available space for the processed CAN frame type */418 /* get available space for the processed CAN frame type */
412 int max_len = nskb->len - offsetof(struct can_frame, data);419 int max_len = nskb->len - offsetof(struct canfd_frame, data);
413 420
414 /* dlc may have changed, make sure it fits to the CAN frame */421 /* dlc may have changed, make sure it fits to the CAN frame */
415 if (cf->can_dlc > max_len)422 if (cf->len > max_len)
416 goto out_delete;423 goto out_delete;
417 424
418 /* check for checksum updates in classic CAN length only */425 /* check for checksum updates in classic CAN length only */
419 if (gwj->mod.csumfunc.crc8) {426 if (gwj->mod.csumfunc.crc8) {
420 if (cf->can_dlc > 8)427 if (cf->len > 8)
421 goto out_delete;428 goto out_delete;
422 429
423 (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8);430 (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8);
424 }431 }
425 432
426 if (gwj->mod.csumfunc.xor) {433 if (gwj->mod.csumfunc.xor) {
427 if (cf->can_dlc > 8)434 if (cf->len > 8)
428 goto out_delete;435 goto out_delete;
429 436
430 (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor);437 (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor);
@@ -492,7 +499,6 @@ static int cgw_notifier(struct notifier_block *nb, · 61 unmodified lines
492static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,499static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
493 u32 pid, u32 seq, int flags)500 u32 pid, u32 seq, int flags)
494{501{
495 struct cgw_frame_mod mb;
496 struct rtcanmsg *rtcan;502 struct rtcanmsg *rtcan;
497 struct nlmsghdr *nlh;503 struct nlmsghdr *nlh;
498 504
@@ -529,32 +535,36 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type, · 30 unmodified lines
529 goto cancel;535 goto cancel;
530 }536 }
531 537
532 if (gwj->mod.modtype.and) {538 if (1) {
533 memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf));539 struct cgw_frame_mod mb;
534 mb.modtype = gwj->mod.modtype.and;
535 if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
536 goto cancel;
537 }
538 540
539 if (gwj->mod.modtype.or) {541 if (gwj->mod.modtype.and) {
540 memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf));542 memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf));
541 mb.modtype = gwj->mod.modtype.or;543 mb.modtype = gwj->mod.modtype.and;
542 if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)544 if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
543 goto cancel;545 goto cancel;
544 }546 }
545 547
546 if (gwj->mod.modtype.xor) {548 if (gwj->mod.modtype.or) {
547 memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf));549 memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf));
548 mb.modtype = gwj->mod.modtype.xor;550 mb.modtype = gwj->mod.modtype.or;
549 if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)551 if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)
550 goto cancel;552 goto cancel;
551 }553 }
552 554
553 if (gwj->mod.modtype.set) {555 if (gwj->mod.modtype.xor) {
554 memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf));556 memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf));
555 mb.modtype = gwj->mod.modtype.set;557 mb.modtype = gwj->mod.modtype.xor;
556 if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)558 if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)
557 goto cancel;559 goto cancel;
560 }
561
562 if (gwj->mod.modtype.set) {
563 memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf));
564 mb.modtype = gwj->mod.modtype.set;
565 if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)
566 goto cancel;
567 }
558 }568 }
559 569
560 if (gwj->mod.uid) {570 if (gwj->mod.uid) {
@@ -642,7 +652,6 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod, · 81 unmodified lines
642 u8 gwtype, void *gwtypeattr, u8 *limhops)652 u8 gwtype, void *gwtypeattr, u8 *limhops)
643{653{
644 struct nlattr *tb[CGW_MAX + 1];654 struct nlattr *tb[CGW_MAX + 1];
645 struct cgw_frame_mod mb;
646 int modidx = 0;655 int modidx = 0;
647 int err = 0;656 int err = 0;
648 657
@@ -662,69 +671,72 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod, · 13 unmodified lines
662 }671 }
663 672
664 /* check for AND/OR/XOR/SET modifications */673 /* check for AND/OR/XOR/SET modifications */
674 if (1) {
675 struct cgw_frame_mod mb;
665 676
666 if (tb[CGW_MOD_AND]) {677 if (tb[CGW_MOD_AND]) {
667 nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN);678 nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN);
668 679
669 canframecpy(&mod->modframe.and, &mb.cf);680 canframecpy(&mod->modframe.and, &mb.cf);
670 mod->modtype.and = mb.modtype;681 mod->modtype.and = mb.modtype;
671 682
672 if (mb.modtype & CGW_MOD_ID)683 if (mb.modtype & CGW_MOD_ID)
673 mod->modfunc[modidx++] = mod_and_id;684 mod->modfunc[modidx++] = mod_and_id;
674 685
675 if (mb.modtype & CGW_MOD_DLC)686 if (mb.modtype & CGW_MOD_LEN)
676 mod->modfunc[modidx++] = mod_and_dlc;687 mod->modfunc[modidx++] = mod_and_len;
677 688
678 if (mb.modtype & CGW_MOD_DATA)689 if (mb.modtype & CGW_MOD_DATA)
679 mod->modfunc[modidx++] = mod_and_data;690 mod->modfunc[modidx++] = mod_and_data;
680 }691 }
681 692
682 if (tb[CGW_MOD_OR]) {693 if (tb[CGW_MOD_OR]) {
683 nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN);694 nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN);
684 695
685 canframecpy(&mod->modframe.or, &mb.cf);696 canframecpy(&mod->modframe.or, &mb.cf);
686 mod->modtype.or = mb.modtype;697 mod->modtype.or = mb.modtype;
687 698
688 if (mb.modtype & CGW_MOD_ID)699 if (mb.modtype & CGW_MOD_ID)
689 mod->modfunc[modidx++] = mod_or_id;700 mod->modfunc[modidx++] = mod_or_id;
690 701
691 if (mb.modtype & CGW_MOD_DLC)702 if (mb.modtype & CGW_MOD_LEN)
692 mod->modfunc[modidx++] = mod_or_dlc;703 mod->modfunc[modidx++] = mod_or_len;
693 704
694 if (mb.modtype & CGW_MOD_DATA)705 if (mb.modtype & CGW_MOD_DATA)
695 mod->modfunc[modidx++] = mod_or_data;706 mod->modfunc[modidx++] = mod_or_data;
696 }707 }
697 708
698 if (tb[CGW_MOD_XOR]) {709 if (tb[CGW_MOD_XOR]) {
699 nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN);710 nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN);
700 711
701 canframecpy(&mod->modframe.xor, &mb.cf);712 canframecpy(&mod->modframe.xor, &mb.cf);
702 mod->modtype.xor = mb.modtype;713 mod->modtype.xor = mb.modtype;
703 714
704 if (mb.modtype & CGW_MOD_ID)715 if (mb.modtype & CGW_MOD_ID)
705 mod->modfunc[modidx++] = mod_xor_id;716 mod->modfunc[modidx++] = mod_xor_id;
706 717
707 if (mb.modtype & CGW_MOD_DLC)718 if (mb.modtype & CGW_MOD_LEN)
708 mod->modfunc[modidx++] = mod_xor_dlc;719 mod->modfunc[modidx++] = mod_xor_len;
709 720
710 if (mb.modtype & CGW_MOD_DATA)721 if (mb.modtype & CGW_MOD_DATA)
711 mod->modfunc[modidx++] = mod_xor_data;722 mod->modfunc[modidx++] = mod_xor_data;
712 }723 }
713 724
714 if (tb[CGW_MOD_SET]) {725 if (tb[CGW_MOD_SET]) {
715 nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN);726 nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN);
716 727
717 canframecpy(&mod->modframe.set, &mb.cf);728 canframecpy(&mod->modframe.set, &mb.cf);
718 mod->modtype.set = mb.modtype;729 mod->modtype.set = mb.modtype;
719 730
720 if (mb.modtype & CGW_MOD_ID)731 if (mb.modtype & CGW_MOD_ID)
721 mod->modfunc[modidx++] = mod_set_id;732 mod->modfunc[modidx++] = mod_set_id;
722 733
723 if (mb.modtype & CGW_MOD_DLC)734 if (mb.modtype & CGW_MOD_LEN)
724 mod->modfunc[modidx++] = mod_set_dlc;735 mod->modfunc[modidx++] = mod_set_len;
725 736
726 if (mb.modtype & CGW_MOD_DATA)737 if (mb.modtype & CGW_MOD_DATA)
727 mod->modfunc[modidx++] = mod_set_data;738 mod->modfunc[modidx++] = mod_set_data;
739 }
728 }740 }
729 741
730 /* check for checksum operations after CAN frame modifications */742 /* check for checksum operations after CAN frame modifications */