Skip to content

Commit ce07183

Browse files
committed
Merge branch 'netlink_ext_ACK'
Johannes Berg says: ==================== netlink extended ACK reporting Changes since v4: * use __NLMSGERR_ATTR_MAX instead of NUM_NLMSGERR_ATTRS Changes since v3: * Add NLM_F_CAPPED and NLM_F_ACK_TLVS flags, to allow entirely stateless parsing of the ACK messages by looking at the new flags. Need to check NLM_F_ACK_TLVS first, since capping can be done in kernels before this patchset without setting the flag. * Remove "missing_attr" functionality - this can obviously be added back rather easily, but I'd rather have more discussion about the nesting problem there. * Improve documentation of NLMSGERR_ATTR_OFFS * Improve message structure documentation, documenting that the request message is always capped for success cases * fix nlmsg_len of the outer message by calling nlmsg_end() * fix memcpy() of the request in success cases, going back to the original code that I'd changed before due to the payload adjustments that I reverted when introducing tlvlen Changes since v2: * add NUM_NLMSGERR_ATTRS, NLMSGERR_ATTR_MAX * fix cookie length to 20 (sha-1 length) * move struct members for cookie to patch 3 where they should be * another cleanup suggested by David Ahern Changes since v1: * credit Pablo and Jamal * incorporate suggestion from David Ahern * fix compilation in decnet ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents fb9eb89 + fe52145 commit ce07183

File tree

139 files changed

+672
-427
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+672
-427
lines changed

crypto/crypto_user.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,8 @@ static const struct crypto_link {
483483
[CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng },
484484
};
485485

486-
static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
486+
static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
487+
struct netlink_ext_ack *extack)
487488
{
488489
struct nlattr *attrs[CRYPTOCFGA_MAX+1];
489490
const struct crypto_link *link;
@@ -522,7 +523,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
522523
}
523524

524525
err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
525-
crypto_policy);
526+
crypto_policy, extack);
526527
if (err < 0)
527528
return err;
528529

drivers/block/drbd/drbd_nla.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
3434

3535
err = drbd_nla_check_mandatory(maxtype, nla);
3636
if (!err)
37-
err = nla_parse_nested(tb, maxtype, nla, policy);
37+
err = nla_parse_nested(tb, maxtype, nla, policy, NULL);
3838

3939
return err;
4040
}

drivers/infiniband/core/addr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static inline bool ib_nl_is_good_ip_resp(const struct nlmsghdr *nlh)
8888
return false;
8989

9090
ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
91-
nlmsg_len(nlh), ib_nl_addr_policy);
91+
nlmsg_len(nlh), ib_nl_addr_policy, NULL);
9292
if (ret)
9393
return false;
9494

drivers/infiniband/core/iwpm_util.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,14 @@ int iwpm_parse_nlmsg(struct netlink_callback *cb, int policy_max,
472472
int ret;
473473
const char *err_str = "";
474474

475-
ret = nlmsg_validate(cb->nlh, nlh_len, policy_max-1, nlmsg_policy);
475+
ret = nlmsg_validate(cb->nlh, nlh_len, policy_max - 1, nlmsg_policy,
476+
NULL);
476477
if (ret) {
477478
err_str = "Invalid attribute";
478479
goto parse_nlmsg_error;
479480
}
480-
ret = nlmsg_parse(cb->nlh, nlh_len, nltb, policy_max-1, nlmsg_policy);
481+
ret = nlmsg_parse(cb->nlh, nlh_len, nltb, policy_max - 1,
482+
nlmsg_policy, NULL);
481483
if (ret) {
482484
err_str = "Unable to parse the nlmsg";
483485
goto parse_nlmsg_error;

drivers/infiniband/core/netlink.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh,
146146
}
147147
EXPORT_SYMBOL(ibnl_put_attr);
148148

149-
static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
149+
static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
150+
struct netlink_ext_ack *extack)
150151
{
151152
struct ibnl_client *client;
152153
int type = nlh->nlmsg_type;
@@ -209,7 +210,7 @@ static void ibnl_rcv_reply_skb(struct sk_buff *skb)
209210
if (nlh->nlmsg_flags & NLM_F_REQUEST)
210211
return;
211212

212-
ibnl_rcv_msg(skb, nlh);
213+
ibnl_rcv_msg(skb, nlh, NULL);
213214

214215
msglen = NLMSG_ALIGN(nlh->nlmsg_len);
215216
if (msglen > skb->len)

drivers/infiniband/core/sa_query.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb,
808808
return -EPERM;
809809

810810
ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
811-
nlmsg_len(nlh), ib_nl_policy);
811+
nlmsg_len(nlh), ib_nl_policy, NULL);
812812
attr = (const struct nlattr *)tb[LS_NLA_TYPE_TIMEOUT];
813813
if (ret || !attr)
814814
goto settimeout_out;
@@ -860,7 +860,7 @@ static inline int ib_nl_is_good_resolve_resp(const struct nlmsghdr *nlh)
860860
return 0;
861861

862862
ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
863-
nlmsg_len(nlh), ib_nl_policy);
863+
nlmsg_len(nlh), ib_nl_policy, NULL);
864864
if (ret)
865865
return 0;
866866

drivers/net/macsec.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,8 +1590,9 @@ static int parse_sa_config(struct nlattr **attrs, struct nlattr **tb_sa)
15901590
if (!attrs[MACSEC_ATTR_SA_CONFIG])
15911591
return -EINVAL;
15921592

1593-
if (nla_parse_nested(tb_sa, MACSEC_SA_ATTR_MAX, attrs[MACSEC_ATTR_SA_CONFIG],
1594-
macsec_genl_sa_policy))
1593+
if (nla_parse_nested(tb_sa, MACSEC_SA_ATTR_MAX,
1594+
attrs[MACSEC_ATTR_SA_CONFIG],
1595+
macsec_genl_sa_policy, NULL))
15951596
return -EINVAL;
15961597

15971598
return 0;
@@ -1602,8 +1603,9 @@ static int parse_rxsc_config(struct nlattr **attrs, struct nlattr **tb_rxsc)
16021603
if (!attrs[MACSEC_ATTR_RXSC_CONFIG])
16031604
return -EINVAL;
16041605

1605-
if (nla_parse_nested(tb_rxsc, MACSEC_RXSC_ATTR_MAX, attrs[MACSEC_ATTR_RXSC_CONFIG],
1606-
macsec_genl_rxsc_policy))
1606+
if (nla_parse_nested(tb_rxsc, MACSEC_RXSC_ATTR_MAX,
1607+
attrs[MACSEC_ATTR_RXSC_CONFIG],
1608+
macsec_genl_rxsc_policy, NULL))
16071609
return -EINVAL;
16081610

16091611
return 0;

drivers/net/team/team.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2471,7 +2471,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
24712471
goto team_put;
24722472
}
24732473
err = nla_parse_nested(opt_attrs, TEAM_ATTR_OPTION_MAX,
2474-
nl_option, team_nl_option_policy);
2474+
nl_option, team_nl_option_policy,
2475+
info->extack);
24752476
if (err)
24762477
goto team_put;
24772478
if (!opt_attrs[TEAM_ATTR_OPTION_NAME] ||

drivers/net/veth.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
368368
ifmp = nla_data(nla_peer);
369369
err = rtnl_nla_parse_ifla(peer_tb,
370370
nla_data(nla_peer) + sizeof(struct ifinfomsg),
371-
nla_len(nla_peer) - sizeof(struct ifinfomsg));
371+
nla_len(nla_peer) - sizeof(struct ifinfomsg),
372+
NULL);
372373
if (err < 0)
373374
return err;
374375

drivers/net/wireless/ath/ath10k/testmode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,8 @@ int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
420420
struct nlattr *tb[ATH10K_TM_ATTR_MAX + 1];
421421
int ret;
422422

423-
ret = nla_parse(tb, ATH10K_TM_ATTR_MAX, data, len,
424-
ath10k_tm_policy);
423+
ret = nla_parse(tb, ATH10K_TM_ATTR_MAX, data, len, ath10k_tm_policy,
424+
NULL);
425425
if (ret)
426426
return ret;
427427

drivers/net/wireless/ath/ath6kl/testmode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
7474
int err, buf_len;
7575
void *buf;
7676

77-
err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
78-
ath6kl_tm_policy);
77+
err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, ath6kl_tm_policy,
78+
NULL);
7979
if (err)
8080
return err;
8181

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3711,7 +3711,8 @@ static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
37113711
int err;
37123712
u32 noa_duration;
37133713

3714-
err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy);
3714+
err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy,
3715+
NULL);
37153716
if (err)
37163717
return err;
37173718

drivers/net/wireless/mac80211_hwsim.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy,
389389
u32 val;
390390

391391
err = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
392-
hwsim_vendor_test_policy);
392+
hwsim_vendor_test_policy, NULL);
393393
if (err)
394394
return err;
395395
if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])
@@ -1852,7 +1852,7 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
18521852
int err, ps;
18531853

18541854
err = nla_parse(tb, HWSIM_TM_ATTR_MAX, data, len,
1855-
hwsim_testmode_policy);
1855+
hwsim_testmode_policy, NULL);
18561856
if (err)
18571857
return err;
18581858

drivers/net/wireless/marvell/mwifiex/cfg80211.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4016,8 +4016,8 @@ static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
40164016
if (!priv)
40174017
return -EINVAL;
40184018

4019-
err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len,
4020-
mwifiex_tm_policy);
4019+
err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len, mwifiex_tm_policy,
4020+
NULL);
40214021
if (err)
40224022
return err;
40234023

drivers/net/wireless/ti/wlcore/testmode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
366366
u32 nla_cmd;
367367
int err;
368368

369-
err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);
369+
err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy,
370+
NULL);
370371
if (err)
371372
return err;
372373

drivers/net/wireless/ti/wlcore/vendor_cmd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy,
4141
return -EINVAL;
4242

4343
ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
44-
wlcore_vendor_attr_policy);
44+
wlcore_vendor_attr_policy, NULL);
4545
if (ret)
4646
return ret;
4747

@@ -116,7 +116,7 @@ wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy,
116116
return -EINVAL;
117117

118118
ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
119-
wlcore_vendor_attr_policy);
119+
wlcore_vendor_attr_policy, NULL);
120120
if (ret)
121121
return ret;
122122

drivers/scsi/scsi_netlink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
111111

112112
next_msg:
113113
if ((err) || (nlh->nlmsg_flags & NLM_F_ACK))
114-
netlink_ack(skb, nlh, err);
114+
netlink_ack(skb, nlh, err, NULL);
115115

116116
skb_pull(skb, rlen);
117117
}

include/linux/netlink.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,42 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
6262
return __netlink_kernel_create(net, unit, THIS_MODULE, cfg);
6363
}
6464

65+
/* this can be increased when necessary - don't expose to userland */
66+
#define NETLINK_MAX_COOKIE_LEN 20
67+
68+
/**
69+
* struct netlink_ext_ack - netlink extended ACK report struct
70+
* @_msg: message string to report - don't access directly, use
71+
* %NL_SET_ERR_MSG
72+
* @bad_attr: attribute with error
73+
* @cookie: cookie data to return to userspace (for success)
74+
* @cookie_len: actual cookie data length
75+
*/
76+
struct netlink_ext_ack {
77+
const char *_msg;
78+
const struct nlattr *bad_attr;
79+
u8 cookie[NETLINK_MAX_COOKIE_LEN];
80+
u8 cookie_len;
81+
};
82+
83+
/* Always use this macro, this allows later putting the
84+
* message into a separate section or such for things
85+
* like translation or listing all possible messages.
86+
* Currently string formatting is not supported (due
87+
* to the lack of an output buffer.)
88+
*/
89+
#define NL_SET_ERR_MSG(extack, msg) do { \
90+
static const char _msg[] = (msg); \
91+
\
92+
(extack)->_msg = _msg; \
93+
} while (0)
94+
6595
extern void netlink_kernel_release(struct sock *sk);
6696
extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
6797
extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
6898
extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group);
69-
extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
99+
extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
100+
const struct netlink_ext_ack *extack);
70101
extern int netlink_has_listeners(struct sock *sk, unsigned int group);
71102

72103
extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock);

include/net/genetlink.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct nlattr **genl_family_attrbuf(const struct genl_family *family);
8484
* @attrs: netlink attributes
8585
* @_net: network namespace
8686
* @user_ptr: user pointers
87+
* @extack: extended ACK report struct
8788
*/
8889
struct genl_info {
8990
u32 snd_seq;
@@ -94,6 +95,7 @@ struct genl_info {
9495
struct nlattr ** attrs;
9596
possible_net_t _net;
9697
void * user_ptr[2];
98+
struct netlink_ext_ack *extack;
9799
};
98100

99101
static inline struct net *genl_info_net(struct genl_info *info)
@@ -106,6 +108,16 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
106108
write_pnet(&info->_net, net);
107109
}
108110

111+
#define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg)
112+
113+
static inline int genl_err_attr(struct genl_info *info, int err,
114+
struct nlattr *attr)
115+
{
116+
info->extack->bad_attr = attr;
117+
118+
return err;
119+
}
120+
109121
/**
110122
* struct genl_ops - generic netlink operations
111123
* @cmd: command identifier
@@ -162,14 +174,16 @@ genlmsg_nlhdr(void *user_hdr, const struct genl_family *family)
162174
* @tb: destination array with maxtype+1 elements
163175
* @maxtype: maximum attribute type to be expected
164176
* @policy: validation policy
165-
* */
177+
* @extack: extended ACK report struct
178+
*/
166179
static inline int genlmsg_parse(const struct nlmsghdr *nlh,
167180
const struct genl_family *family,
168181
struct nlattr *tb[], int maxtype,
169-
const struct nla_policy *policy)
182+
const struct nla_policy *policy,
183+
struct netlink_ext_ack *extack)
170184
{
171185
return nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
172-
policy);
186+
policy, extack);
173187
}
174188

175189
/**

0 commit comments

Comments
 (0)