af_ieee802154: add support for WANT_ACK socket option
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
74eda55db4
commit
99eb855864
|
@ -54,4 +54,9 @@ struct sockaddr_ieee802154 {
|
||||||
struct ieee802154_addr addr;
|
struct ieee802154_addr addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* get/setsockopt */
|
||||||
|
#define SOL_IEEE802154 0
|
||||||
|
|
||||||
|
#define WPAN_WANTACK 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct dgram_sock {
|
||||||
struct ieee802154_addr dst_addr;
|
struct ieee802154_addr dst_addr;
|
||||||
|
|
||||||
unsigned bound:1;
|
unsigned bound:1;
|
||||||
|
unsigned want_ack:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct dgram_sock *dgram_sk(const struct sock *sk)
|
static inline struct dgram_sock *dgram_sk(const struct sock *sk)
|
||||||
|
@ -51,7 +52,6 @@ static inline struct dgram_sock *dgram_sk(const struct sock *sk)
|
||||||
return container_of(sk, struct dgram_sock, sk);
|
return container_of(sk, struct dgram_sock, sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dgram_hash(struct sock *sk)
|
static void dgram_hash(struct sock *sk)
|
||||||
{
|
{
|
||||||
write_lock_bh(&dgram_lock);
|
write_lock_bh(&dgram_lock);
|
||||||
|
@ -74,6 +74,7 @@ static int dgram_init(struct sock *sk)
|
||||||
|
|
||||||
ro->dst_addr.addr_type = IEEE802154_ADDR_LONG;
|
ro->dst_addr.addr_type = IEEE802154_ADDR_LONG;
|
||||||
ro->dst_addr.pan_id = 0xffff;
|
ro->dst_addr.pan_id = 0xffff;
|
||||||
|
ro->want_ack = 1;
|
||||||
memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr));
|
memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +238,10 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
|
||||||
|
|
||||||
skb_reset_network_header(skb);
|
skb_reset_network_header(skb);
|
||||||
|
|
||||||
mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA | MAC_CB_FLAG_ACKREQ;
|
mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA;
|
||||||
|
if (ro->want_ack)
|
||||||
|
mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ;
|
||||||
|
|
||||||
mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
|
mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
|
||||||
err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr,
|
err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr,
|
||||||
ro->bound ? &ro->src_addr : NULL, size);
|
ro->bound ? &ro->src_addr : NULL, size);
|
||||||
|
@ -382,13 +386,59 @@ int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
|
||||||
static int dgram_getsockopt(struct sock *sk, int level, int optname,
|
static int dgram_getsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user *optlen)
|
char __user *optval, int __user *optlen)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
struct dgram_sock *ro = dgram_sk(sk);
|
||||||
|
|
||||||
|
int val, len;
|
||||||
|
|
||||||
|
if (level != SOL_IEEE802154)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (get_user(len, optlen))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
len = min_t(unsigned int, len, sizeof(int));
|
||||||
|
|
||||||
|
switch (optname) {
|
||||||
|
case WPAN_WANTACK:
|
||||||
|
val = ro->want_ack;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOPROTOOPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (put_user(len, optlen))
|
||||||
|
return -EFAULT;
|
||||||
|
if (copy_to_user(optval, &val, len))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dgram_setsockopt(struct sock *sk, int level, int optname,
|
static int dgram_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int __user optlen)
|
char __user *optval, int __user optlen)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
struct dgram_sock *ro = dgram_sk(sk);
|
||||||
|
int val;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (optlen < sizeof(int))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (get_user(val, (int __user *)optval))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
lock_sock(sk);
|
||||||
|
|
||||||
|
switch (optname) {
|
||||||
|
case WPAN_WANTACK:
|
||||||
|
ro->want_ack = !!val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = -ENOPROTOOPT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
release_sock(sk);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proto ieee802154_dgram_prot = {
|
struct proto ieee802154_dgram_prot = {
|
||||||
|
|
Loading…
Reference in New Issue