Loading include/net/af_ieee802154.h +5 −0 Original line number Diff line number Diff line Loading @@ -54,4 +54,9 @@ struct sockaddr_ieee802154 { struct ieee802154_addr addr; }; /* get/setsockopt */ #define SOL_IEEE802154 0 #define WPAN_WANTACK 0 #endif net/ieee802154/dgram.c +54 −4 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ struct dgram_sock { struct ieee802154_addr dst_addr; unsigned bound:1; unsigned want_ack:1; }; static inline struct dgram_sock *dgram_sk(const struct sock *sk) Loading @@ -51,7 +52,6 @@ static inline struct dgram_sock *dgram_sk(const struct sock *sk) return container_of(sk, struct dgram_sock, sk); } static void dgram_hash(struct sock *sk) { write_lock_bh(&dgram_lock); Loading @@ -74,6 +74,7 @@ static int dgram_init(struct sock *sk) ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; ro->dst_addr.pan_id = 0xffff; ro->want_ack = 1; memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); return 0; } Loading Loading @@ -237,7 +238,10 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, 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); err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr, ro->bound ? &ro->src_addr : NULL, size); Loading Loading @@ -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, char __user *optval, int __user *optlen) { 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, 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 = { Loading Loading
include/net/af_ieee802154.h +5 −0 Original line number Diff line number Diff line Loading @@ -54,4 +54,9 @@ struct sockaddr_ieee802154 { struct ieee802154_addr addr; }; /* get/setsockopt */ #define SOL_IEEE802154 0 #define WPAN_WANTACK 0 #endif
net/ieee802154/dgram.c +54 −4 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ struct dgram_sock { struct ieee802154_addr dst_addr; unsigned bound:1; unsigned want_ack:1; }; static inline struct dgram_sock *dgram_sk(const struct sock *sk) Loading @@ -51,7 +52,6 @@ static inline struct dgram_sock *dgram_sk(const struct sock *sk) return container_of(sk, struct dgram_sock, sk); } static void dgram_hash(struct sock *sk) { write_lock_bh(&dgram_lock); Loading @@ -74,6 +74,7 @@ static int dgram_init(struct sock *sk) ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; ro->dst_addr.pan_id = 0xffff; ro->want_ack = 1; memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); return 0; } Loading Loading @@ -237,7 +238,10 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, 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); err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr, ro->bound ? &ro->src_addr : NULL, size); Loading Loading @@ -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, char __user *optval, int __user *optlen) { 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, 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 = { Loading