Commit 43559893 authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-next-for-4.2-20150609' of...

Merge tag 'linux-can-next-for-4.2-20150609' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2015-05-06

this is a pull request of a two patches for net-next.

The first patch is by Tomas Krcka, he fixes the (currently unused)
register address for acceptance filters. Oliver Hartkopp contributes a
patch for the cangw, where an optional UID is added to reference
routing jobs.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c3eee1fb dd895d7f
...@@ -190,10 +190,11 @@ ...@@ -190,10 +190,11 @@
#define RXBEID0_OFF 4 #define RXBEID0_OFF 4
#define RXBDLC_OFF 5 #define RXBDLC_OFF 5
#define RXBDAT_OFF 6 #define RXBDAT_OFF 6
#define RXFSIDH(n) ((n) * 4) #define RXFSID(n) ((n < 3) ? 0 : 4)
#define RXFSIDL(n) ((n) * 4 + 1) #define RXFSIDH(n) ((n) * 4 + RXFSID(n))
#define RXFEID8(n) ((n) * 4 + 2) #define RXFSIDL(n) ((n) * 4 + 1 + RXFSID(n))
#define RXFEID0(n) ((n) * 4 + 3) #define RXFEID8(n) ((n) * 4 + 2 + RXFSID(n))
#define RXFEID0(n) ((n) * 4 + 3 + RXFSID(n))
#define RXMSIDH(n) ((n) * 4 + 0x20) #define RXMSIDH(n) ((n) * 4 + 0x20)
#define RXMSIDL(n) ((n) * 4 + 0x21) #define RXMSIDL(n) ((n) * 4 + 0x21)
#define RXMEID8(n) ((n) * 4 + 0x22) #define RXMEID8(n) ((n) * 4 + 0x22)
......
...@@ -78,6 +78,7 @@ enum { ...@@ -78,6 +78,7 @@ enum {
CGW_FILTER, /* specify struct can_filter on source CAN device */ CGW_FILTER, /* specify struct can_filter on source CAN device */
CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */ CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */
CGW_LIM_HOPS, /* limit the number of hops of this specific rule */ CGW_LIM_HOPS, /* limit the number of hops of this specific rule */
CGW_MOD_UID, /* user defined identifier for modification updates */
__CGW_MAX __CGW_MAX
}; };
...@@ -162,6 +163,10 @@ enum { ...@@ -162,6 +163,10 @@ enum {
* load time of the can-gw module). This value is used to reduce the number of * load time of the can-gw module). This value is used to reduce the number of
* possible hops for this gateway rule to a value smaller then max_hops. * possible hops for this gateway rule to a value smaller then max_hops.
* *
* CGW_MOD_UID (length 4 bytes):
* Optional non-zero user defined routing job identifier to alter existing
* modification settings at runtime.
*
* CGW_CS_XOR (length 4 bytes): * CGW_CS_XOR (length 4 bytes):
* Set a simple XOR checksum starting with an initial value into * Set a simple XOR checksum starting with an initial value into
* data[result-idx] using data[start-idx] .. data[end-idx] * data[result-idx] using data[start-idx] .. data[end-idx]
......
...@@ -110,6 +110,7 @@ struct cf_mod { ...@@ -110,6 +110,7 @@ struct cf_mod {
void (*xor)(struct can_frame *cf, struct cgw_csum_xor *xor); void (*xor)(struct can_frame *cf, struct cgw_csum_xor *xor);
void (*crc8)(struct can_frame *cf, struct cgw_csum_crc8 *crc8); void (*crc8)(struct can_frame *cf, struct cgw_csum_crc8 *crc8);
} csumfunc; } csumfunc;
u32 uid;
}; };
...@@ -548,6 +549,11 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type, ...@@ -548,6 +549,11 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
goto cancel; goto cancel;
} }
if (gwj->mod.uid) {
if (nla_put_u32(skb, CGW_MOD_UID, gwj->mod.uid) < 0)
goto cancel;
}
if (gwj->mod.csumfunc.crc8) { if (gwj->mod.csumfunc.crc8) {
if (nla_put(skb, CGW_CS_CRC8, CGW_CS_CRC8_LEN, if (nla_put(skb, CGW_CS_CRC8, CGW_CS_CRC8_LEN,
&gwj->mod.csum.crc8) < 0) &gwj->mod.csum.crc8) < 0)
...@@ -619,6 +625,7 @@ static const struct nla_policy cgw_policy[CGW_MAX+1] = { ...@@ -619,6 +625,7 @@ static const struct nla_policy cgw_policy[CGW_MAX+1] = {
[CGW_DST_IF] = { .type = NLA_U32 }, [CGW_DST_IF] = { .type = NLA_U32 },
[CGW_FILTER] = { .len = sizeof(struct can_filter) }, [CGW_FILTER] = { .len = sizeof(struct can_filter) },
[CGW_LIM_HOPS] = { .type = NLA_U8 }, [CGW_LIM_HOPS] = { .type = NLA_U8 },
[CGW_MOD_UID] = { .type = NLA_U32 },
}; };
/* check for common and gwtype specific attributes */ /* check for common and gwtype specific attributes */
...@@ -761,6 +768,10 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod, ...@@ -761,6 +768,10 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
else else
mod->csumfunc.xor = cgw_csum_xor_neg; mod->csumfunc.xor = cgw_csum_xor_neg;
} }
if (tb[CGW_MOD_UID]) {
nla_memcpy(&mod->uid, tb[CGW_MOD_UID], sizeof(u32));
}
} }
if (gwtype == CGW_TYPE_CAN_CAN) { if (gwtype == CGW_TYPE_CAN_CAN) {
...@@ -802,6 +813,8 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -802,6 +813,8 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh)
{ {
struct rtcanmsg *r; struct rtcanmsg *r;
struct cgw_job *gwj; struct cgw_job *gwj;
struct cf_mod mod;
struct can_can_gw ccgw;
u8 limhops = 0; u8 limhops = 0;
int err = 0; int err = 0;
...@@ -819,6 +832,36 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -819,6 +832,36 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh)
if (r->gwtype != CGW_TYPE_CAN_CAN) if (r->gwtype != CGW_TYPE_CAN_CAN)
return -EINVAL; return -EINVAL;
err = cgw_parse_attr(nlh, &mod, CGW_TYPE_CAN_CAN, &ccgw, &limhops);
if (err < 0)
return err;
if (mod.uid) {
ASSERT_RTNL();
/* check for updating an existing job with identical uid */
hlist_for_each_entry(gwj, &cgw_list, list) {
if (gwj->mod.uid != mod.uid)
continue;
/* interfaces & filters must be identical */
if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw)))
return -EINVAL;
/* update modifications with disabled softirq & quit */
local_bh_disable();
memcpy(&gwj->mod, &mod, sizeof(mod));
local_bh_enable();
return 0;
}
}
/* ifindex == 0 is not allowed for job creation */
if (!ccgw.src_idx || !ccgw.dst_idx)
return -ENODEV;
gwj = kmem_cache_alloc(cgw_cache, GFP_KERNEL); gwj = kmem_cache_alloc(cgw_cache, GFP_KERNEL);
if (!gwj) if (!gwj)
return -ENOMEM; return -ENOMEM;
...@@ -828,18 +871,14 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -828,18 +871,14 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh)
gwj->deleted_frames = 0; gwj->deleted_frames = 0;
gwj->flags = r->flags; gwj->flags = r->flags;
gwj->gwtype = r->gwtype; gwj->gwtype = r->gwtype;
gwj->limit_hops = limhops;
err = cgw_parse_attr(nlh, &gwj->mod, CGW_TYPE_CAN_CAN, &gwj->ccgw, /* insert already parsed information */
&limhops); memcpy(&gwj->mod, &mod, sizeof(mod));
if (err < 0) memcpy(&gwj->ccgw, &ccgw, sizeof(ccgw));
goto out;
err = -ENODEV; err = -ENODEV;
/* ifindex == 0 is not allowed for job creation */
if (!gwj->ccgw.src_idx || !gwj->ccgw.dst_idx)
goto out;
gwj->src.dev = __dev_get_by_index(&init_net, gwj->ccgw.src_idx); gwj->src.dev = __dev_get_by_index(&init_net, gwj->ccgw.src_idx);
if (!gwj->src.dev) if (!gwj->src.dev)
...@@ -856,8 +895,6 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -856,8 +895,6 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh)
if (gwj->dst.dev->type != ARPHRD_CAN) if (gwj->dst.dev->type != ARPHRD_CAN)
goto out; goto out;
gwj->limit_hops = limhops;
ASSERT_RTNL(); ASSERT_RTNL();
err = cgw_register_filter(gwj); err = cgw_register_filter(gwj);
...@@ -931,8 +968,15 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -931,8 +968,15 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh)
if (gwj->limit_hops != limhops) if (gwj->limit_hops != limhops)
continue; continue;
if (memcmp(&gwj->mod, &mod, sizeof(mod))) /* we have a match when uid is enabled and identical */
continue; if (gwj->mod.uid || mod.uid) {
if (gwj->mod.uid != mod.uid)
continue;
} else {
/* no uid => check for identical modifications */
if (memcmp(&gwj->mod, &mod, sizeof(mod)))
continue;
}
/* if (r->gwtype == CGW_TYPE_CAN_CAN) - is made sure here */ /* if (r->gwtype == CGW_TYPE_CAN_CAN) - is made sure here */
if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw))) if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment