Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ieee802154: add del interface command

This patch adds support for deleting a wpan interface via nl802154.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Alexander Aring and committed by
Marcel Holtmann
b821ecd4 0e57547e

+52
+2
include/net/cfg802154.h
··· 43 43 const char *name, 44 44 enum nl802154_iftype type, 45 45 __le64 extended_addr); 46 + int (*del_virtual_intf)(struct wpan_phy *wpan_phy, 47 + struct wpan_dev *wpan_dev); 46 48 int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); 47 49 int (*set_pan_id)(struct wpan_phy *wpan_phy, 48 50 struct wpan_dev *wpan_dev, u16 pan_id);
+28
net/ieee802154/nl802154.c
··· 583 583 type, extended_addr); 584 584 } 585 585 586 + static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info) 587 + { 588 + struct cfg802154_registered_device *rdev = info->user_ptr[0]; 589 + struct wpan_dev *wpan_dev = info->user_ptr[1]; 590 + 591 + if (!rdev->ops->del_virtual_intf) 592 + return -EOPNOTSUPP; 593 + 594 + /* If we remove a wpan device without a netdev then clear 595 + * user_ptr[1] so that nl802154_post_doit won't dereference it 596 + * to check if it needs to do dev_put(). Otherwise it crashes 597 + * since the wpan_dev has been freed, unlike with a netdev where 598 + * we need the dev_put() for the netdev to really be freed. 599 + */ 600 + if (!wpan_dev->netdev) 601 + info->user_ptr[1] = NULL; 602 + 603 + return rdev_del_virtual_intf(rdev, wpan_dev); 604 + } 605 + 586 606 static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) 587 607 { 588 608 struct cfg802154_registered_device *rdev = info->user_ptr[0]; ··· 876 856 .policy = nl802154_policy, 877 857 .flags = GENL_ADMIN_PERM, 878 858 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 859 + NL802154_FLAG_NEED_RTNL, 860 + }, 861 + { 862 + .cmd = NL802154_CMD_DEL_INTERFACE, 863 + .doit = nl802154_del_interface, 864 + .policy = nl802154_policy, 865 + .flags = GENL_ADMIN_PERM, 866 + .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | 879 867 NL802154_FLAG_NEED_RTNL, 880 868 }, 881 869 {
+7
net/ieee802154/rdev-ops.h
··· 29 29 } 30 30 31 31 static inline int 32 + rdev_del_virtual_intf(struct cfg802154_registered_device *rdev, 33 + struct wpan_dev *wpan_dev) 34 + { 35 + return rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev); 36 + } 37 + 38 + static inline int 32 39 rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) 33 40 { 34 41 return rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
+9
net/mac802154/cfg.c
··· 58 58 } 59 59 60 60 static int 61 + ieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev) 62 + { 63 + ieee802154_if_remove(IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev)); 64 + 65 + return 0; 66 + } 67 + 68 + static int 61 69 ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) 62 70 { 63 71 struct ieee802154_local *local = wpan_phy_priv(wpan_phy); ··· 199 191 .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, 200 192 .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, 201 193 .add_virtual_intf = ieee802154_add_iface, 194 + .del_virtual_intf = ieee802154_del_iface, 202 195 .set_channel = ieee802154_set_channel, 203 196 .set_pan_id = ieee802154_set_pan_id, 204 197 .set_short_addr = ieee802154_set_short_addr,
+6
net/mac802154/ieee802154_i.h
··· 115 115 return netdev_priv(dev); 116 116 } 117 117 118 + static inline struct ieee802154_sub_if_data * 119 + IEEE802154_WPAN_DEV_TO_SUB_IF(struct wpan_dev *wpan_dev) 120 + { 121 + return container_of(wpan_dev, struct ieee802154_sub_if_data, wpan_dev); 122 + } 123 + 118 124 static inline bool 119 125 ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata) 120 126 {