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 <davem@davemloft.net>
This commit is contained in:
Коммит
ce07183282
|
@ -483,7 +483,8 @@ static const struct crypto_link {
|
|||
[CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng },
|
||||
};
|
||||
|
||||
static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *attrs[CRYPTOCFGA_MAX+1];
|
||||
const struct crypto_link *link;
|
||||
|
@ -522,7 +523,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
}
|
||||
|
||||
err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
|
||||
crypto_policy);
|
||||
crypto_policy, extack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
|
|||
|
||||
err = drbd_nla_check_mandatory(maxtype, nla);
|
||||
if (!err)
|
||||
err = nla_parse_nested(tb, maxtype, nla, policy);
|
||||
err = nla_parse_nested(tb, maxtype, nla, policy, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ static inline bool ib_nl_is_good_ip_resp(const struct nlmsghdr *nlh)
|
|||
return false;
|
||||
|
||||
ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
|
||||
nlmsg_len(nlh), ib_nl_addr_policy);
|
||||
nlmsg_len(nlh), ib_nl_addr_policy, NULL);
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -472,12 +472,14 @@ int iwpm_parse_nlmsg(struct netlink_callback *cb, int policy_max,
|
|||
int ret;
|
||||
const char *err_str = "";
|
||||
|
||||
ret = nlmsg_validate(cb->nlh, nlh_len, policy_max-1, nlmsg_policy);
|
||||
ret = nlmsg_validate(cb->nlh, nlh_len, policy_max - 1, nlmsg_policy,
|
||||
NULL);
|
||||
if (ret) {
|
||||
err_str = "Invalid attribute";
|
||||
goto parse_nlmsg_error;
|
||||
}
|
||||
ret = nlmsg_parse(cb->nlh, nlh_len, nltb, policy_max-1, nlmsg_policy);
|
||||
ret = nlmsg_parse(cb->nlh, nlh_len, nltb, policy_max - 1,
|
||||
nlmsg_policy, NULL);
|
||||
if (ret) {
|
||||
err_str = "Unable to parse the nlmsg";
|
||||
goto parse_nlmsg_error;
|
||||
|
|
|
@ -146,7 +146,8 @@ nla_put_failure:
|
|||
}
|
||||
EXPORT_SYMBOL(ibnl_put_attr);
|
||||
|
||||
static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct ibnl_client *client;
|
||||
int type = nlh->nlmsg_type;
|
||||
|
@ -209,7 +210,7 @@ static void ibnl_rcv_reply_skb(struct sk_buff *skb)
|
|||
if (nlh->nlmsg_flags & NLM_F_REQUEST)
|
||||
return;
|
||||
|
||||
ibnl_rcv_msg(skb, nlh);
|
||||
ibnl_rcv_msg(skb, nlh, NULL);
|
||||
|
||||
msglen = NLMSG_ALIGN(nlh->nlmsg_len);
|
||||
if (msglen > skb->len)
|
||||
|
|
|
@ -808,7 +808,7 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb,
|
|||
return -EPERM;
|
||||
|
||||
ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
|
||||
nlmsg_len(nlh), ib_nl_policy);
|
||||
nlmsg_len(nlh), ib_nl_policy, NULL);
|
||||
attr = (const struct nlattr *)tb[LS_NLA_TYPE_TIMEOUT];
|
||||
if (ret || !attr)
|
||||
goto settimeout_out;
|
||||
|
@ -860,7 +860,7 @@ static inline int ib_nl_is_good_resolve_resp(const struct nlmsghdr *nlh)
|
|||
return 0;
|
||||
|
||||
ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
|
||||
nlmsg_len(nlh), ib_nl_policy);
|
||||
nlmsg_len(nlh), ib_nl_policy, NULL);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -1590,8 +1590,9 @@ static int parse_sa_config(struct nlattr **attrs, struct nlattr **tb_sa)
|
|||
if (!attrs[MACSEC_ATTR_SA_CONFIG])
|
||||
return -EINVAL;
|
||||
|
||||
if (nla_parse_nested(tb_sa, MACSEC_SA_ATTR_MAX, attrs[MACSEC_ATTR_SA_CONFIG],
|
||||
macsec_genl_sa_policy))
|
||||
if (nla_parse_nested(tb_sa, MACSEC_SA_ATTR_MAX,
|
||||
attrs[MACSEC_ATTR_SA_CONFIG],
|
||||
macsec_genl_sa_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
@ -1602,8 +1603,9 @@ static int parse_rxsc_config(struct nlattr **attrs, struct nlattr **tb_rxsc)
|
|||
if (!attrs[MACSEC_ATTR_RXSC_CONFIG])
|
||||
return -EINVAL;
|
||||
|
||||
if (nla_parse_nested(tb_rxsc, MACSEC_RXSC_ATTR_MAX, attrs[MACSEC_ATTR_RXSC_CONFIG],
|
||||
macsec_genl_rxsc_policy))
|
||||
if (nla_parse_nested(tb_rxsc, MACSEC_RXSC_ATTR_MAX,
|
||||
attrs[MACSEC_ATTR_RXSC_CONFIG],
|
||||
macsec_genl_rxsc_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2471,7 +2471,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
|
|||
goto team_put;
|
||||
}
|
||||
err = nla_parse_nested(opt_attrs, TEAM_ATTR_OPTION_MAX,
|
||||
nl_option, team_nl_option_policy);
|
||||
nl_option, team_nl_option_policy,
|
||||
info->extack);
|
||||
if (err)
|
||||
goto team_put;
|
||||
if (!opt_attrs[TEAM_ATTR_OPTION_NAME] ||
|
||||
|
|
|
@ -368,7 +368,8 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
|
|||
ifmp = nla_data(nla_peer);
|
||||
err = rtnl_nla_parse_ifla(peer_tb,
|
||||
nla_data(nla_peer) + sizeof(struct ifinfomsg),
|
||||
nla_len(nla_peer) - sizeof(struct ifinfomsg));
|
||||
nla_len(nla_peer) - sizeof(struct ifinfomsg),
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -420,8 +420,8 @@ int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
struct nlattr *tb[ATH10K_TM_ATTR_MAX + 1];
|
||||
int ret;
|
||||
|
||||
ret = nla_parse(tb, ATH10K_TM_ATTR_MAX, data, len,
|
||||
ath10k_tm_policy);
|
||||
ret = nla_parse(tb, ATH10K_TM_ATTR_MAX, data, len, ath10k_tm_policy,
|
||||
NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -74,8 +74,8 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
int err, buf_len;
|
||||
void *buf;
|
||||
|
||||
err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
|
||||
ath6kl_tm_policy);
|
||||
err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, ath6kl_tm_policy,
|
||||
NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -3711,7 +3711,8 @@ static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
|
|||
int err;
|
||||
u32 noa_duration;
|
||||
|
||||
err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy);
|
||||
err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy,
|
||||
NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -389,7 +389,7 @@ static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy,
|
|||
u32 val;
|
||||
|
||||
err = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
|
||||
hwsim_vendor_test_policy);
|
||||
hwsim_vendor_test_policy, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])
|
||||
|
@ -1852,7 +1852,7 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
|
|||
int err, ps;
|
||||
|
||||
err = nla_parse(tb, HWSIM_TM_ATTR_MAX, data, len,
|
||||
hwsim_testmode_policy);
|
||||
hwsim_testmode_policy, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -4016,8 +4016,8 @@ static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
if (!priv)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len,
|
||||
mwifiex_tm_policy);
|
||||
err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len, mwifiex_tm_policy,
|
||||
NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -366,7 +366,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
u32 nla_cmd;
|
||||
int err;
|
||||
|
||||
err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);
|
||||
err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy,
|
||||
NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy,
|
|||
return -EINVAL;
|
||||
|
||||
ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
|
||||
wlcore_vendor_attr_policy);
|
||||
wlcore_vendor_attr_policy, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -116,7 +116,7 @@ wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy,
|
|||
return -EINVAL;
|
||||
|
||||
ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
|
||||
wlcore_vendor_attr_policy);
|
||||
wlcore_vendor_attr_policy, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
|
|||
|
||||
next_msg:
|
||||
if ((err) || (nlh->nlmsg_flags & NLM_F_ACK))
|
||||
netlink_ack(skb, nlh, err);
|
||||
netlink_ack(skb, nlh, err, NULL);
|
||||
|
||||
skb_pull(skb, rlen);
|
||||
}
|
||||
|
|
|
@ -62,11 +62,42 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
|
|||
return __netlink_kernel_create(net, unit, THIS_MODULE, cfg);
|
||||
}
|
||||
|
||||
/* this can be increased when necessary - don't expose to userland */
|
||||
#define NETLINK_MAX_COOKIE_LEN 20
|
||||
|
||||
/**
|
||||
* struct netlink_ext_ack - netlink extended ACK report struct
|
||||
* @_msg: message string to report - don't access directly, use
|
||||
* %NL_SET_ERR_MSG
|
||||
* @bad_attr: attribute with error
|
||||
* @cookie: cookie data to return to userspace (for success)
|
||||
* @cookie_len: actual cookie data length
|
||||
*/
|
||||
struct netlink_ext_ack {
|
||||
const char *_msg;
|
||||
const struct nlattr *bad_attr;
|
||||
u8 cookie[NETLINK_MAX_COOKIE_LEN];
|
||||
u8 cookie_len;
|
||||
};
|
||||
|
||||
/* Always use this macro, this allows later putting the
|
||||
* message into a separate section or such for things
|
||||
* like translation or listing all possible messages.
|
||||
* Currently string formatting is not supported (due
|
||||
* to the lack of an output buffer.)
|
||||
*/
|
||||
#define NL_SET_ERR_MSG(extack, msg) do { \
|
||||
static const char _msg[] = (msg); \
|
||||
\
|
||||
(extack)->_msg = _msg; \
|
||||
} while (0)
|
||||
|
||||
extern void netlink_kernel_release(struct sock *sk);
|
||||
extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
|
||||
extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
|
||||
extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group);
|
||||
extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
|
||||
extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
|
||||
const struct netlink_ext_ack *extack);
|
||||
extern int netlink_has_listeners(struct sock *sk, unsigned int group);
|
||||
|
||||
extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock);
|
||||
|
|
|
@ -84,6 +84,7 @@ struct nlattr **genl_family_attrbuf(const struct genl_family *family);
|
|||
* @attrs: netlink attributes
|
||||
* @_net: network namespace
|
||||
* @user_ptr: user pointers
|
||||
* @extack: extended ACK report struct
|
||||
*/
|
||||
struct genl_info {
|
||||
u32 snd_seq;
|
||||
|
@ -94,6 +95,7 @@ struct genl_info {
|
|||
struct nlattr ** attrs;
|
||||
possible_net_t _net;
|
||||
void * user_ptr[2];
|
||||
struct netlink_ext_ack *extack;
|
||||
};
|
||||
|
||||
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)
|
|||
write_pnet(&info->_net, net);
|
||||
}
|
||||
|
||||
#define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg)
|
||||
|
||||
static inline int genl_err_attr(struct genl_info *info, int err,
|
||||
struct nlattr *attr)
|
||||
{
|
||||
info->extack->bad_attr = attr;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct genl_ops - generic netlink operations
|
||||
* @cmd: command identifier
|
||||
|
@ -162,14 +174,16 @@ genlmsg_nlhdr(void *user_hdr, const struct genl_family *family)
|
|||
* @tb: destination array with maxtype+1 elements
|
||||
* @maxtype: maximum attribute type to be expected
|
||||
* @policy: validation policy
|
||||
* */
|
||||
* @extack: extended ACK report struct
|
||||
*/
|
||||
static inline int genlmsg_parse(const struct nlmsghdr *nlh,
|
||||
const struct genl_family *family,
|
||||
struct nlattr *tb[], int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
|
||||
policy);
|
||||
policy, extack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -233,14 +233,17 @@ struct nl_info {
|
|||
};
|
||||
|
||||
int netlink_rcv_skb(struct sk_buff *skb,
|
||||
int (*cb)(struct sk_buff *, struct nlmsghdr *));
|
||||
int (*cb)(struct sk_buff *, struct nlmsghdr *,
|
||||
struct netlink_ext_ack *));
|
||||
int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
|
||||
unsigned int group, int report, gfp_t flags);
|
||||
|
||||
int nla_validate(const struct nlattr *head, int len, int maxtype,
|
||||
const struct nla_policy *policy);
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack);
|
||||
int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
|
||||
int len, const struct nla_policy *policy);
|
||||
int len, const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack);
|
||||
int nla_policy_len(const struct nla_policy *, int);
|
||||
struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype);
|
||||
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
|
||||
|
@ -374,18 +377,20 @@ nlmsg_next(const struct nlmsghdr *nlh, int *remaining)
|
|||
* @tb: destination array with maxtype+1 elements
|
||||
* @maxtype: maximum attribute type to be expected
|
||||
* @policy: validation policy
|
||||
* @extack: extended ACK report struct
|
||||
*
|
||||
* See nla_parse()
|
||||
*/
|
||||
static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
|
||||
struct nlattr *tb[], int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
|
||||
return -EINVAL;
|
||||
|
||||
return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
|
||||
nlmsg_attrlen(nlh, hdrlen), policy);
|
||||
nlmsg_attrlen(nlh, hdrlen), policy, extack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -409,16 +414,19 @@ static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh,
|
|||
* @hdrlen: length of familiy specific header
|
||||
* @maxtype: maximum attribute type to be expected
|
||||
* @policy: validation policy
|
||||
* @extack: extended ACK report struct
|
||||
*/
|
||||
static inline int nlmsg_validate(const struct nlmsghdr *nlh,
|
||||
int hdrlen, int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
|
||||
return -EINVAL;
|
||||
|
||||
return nla_validate(nlmsg_attrdata(nlh, hdrlen),
|
||||
nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
|
||||
nlmsg_attrlen(nlh, hdrlen), maxtype, policy,
|
||||
extack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -739,14 +747,17 @@ nla_find_nested(const struct nlattr *nla, int attrtype)
|
|||
* @maxtype: maximum attribute type to be expected
|
||||
* @nla: attribute containing the nested attributes
|
||||
* @policy: validation policy
|
||||
* @extack: extended ACK report struct
|
||||
*
|
||||
* See nla_parse()
|
||||
*/
|
||||
static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
|
||||
const struct nlattr *nla,
|
||||
const struct nla_policy *policy)
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
|
||||
return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy,
|
||||
extack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1252,6 +1263,7 @@ static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
|
|||
* @start: container attribute
|
||||
* @maxtype: maximum attribute type to be expected
|
||||
* @policy: validation policy
|
||||
* @extack: extended ACK report struct
|
||||
*
|
||||
* Validates all attributes in the nested attribute stream against the
|
||||
* specified policy. Attributes with a type exceeding maxtype will be
|
||||
|
@ -1260,9 +1272,11 @@ static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
|
|||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
static inline int nla_validate_nested(const struct nlattr *start, int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
|
||||
return nla_validate(nla_data(start), nla_len(start), maxtype, policy,
|
||||
extack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -158,7 +158,8 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
|
|||
int rtnl_delete_link(struct net_device *dev);
|
||||
int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm);
|
||||
|
||||
int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len);
|
||||
int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
|
||||
struct netlink_ext_ack *exterr);
|
||||
|
||||
#define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
|
||||
|
||||
|
|
|
@ -69,6 +69,10 @@ struct nlmsghdr {
|
|||
#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
|
||||
#define NLM_F_APPEND 0x800 /* Add to end of list */
|
||||
|
||||
/* Flags for ACK message */
|
||||
#define NLM_F_CAPPED 0x100 /* request was capped */
|
||||
#define NLM_F_ACK_TLVS 0x200 /* extended ACK TVLs were included */
|
||||
|
||||
/*
|
||||
4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
|
||||
4.4BSD CHANGE NLM_F_REPLACE
|
||||
|
@ -101,6 +105,37 @@ struct nlmsghdr {
|
|||
struct nlmsgerr {
|
||||
int error;
|
||||
struct nlmsghdr msg;
|
||||
/*
|
||||
* followed by the message contents unless NETLINK_CAP_ACK was set
|
||||
* or the ACK indicates success (error == 0)
|
||||
* message length is aligned with NLMSG_ALIGN()
|
||||
*/
|
||||
/*
|
||||
* followed by TLVs defined in enum nlmsgerr_attrs
|
||||
* if NETLINK_EXT_ACK was set
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nlmsgerr_attrs - nlmsgerr attributes
|
||||
* @NLMSGERR_ATTR_UNUSED: unused
|
||||
* @NLMSGERR_ATTR_MSG: error message string (string)
|
||||
* @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original
|
||||
* message, counting from the beginning of the header (u32)
|
||||
* @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
|
||||
* be used - in the success case - to identify a created
|
||||
* object or operation or similar (binary)
|
||||
* @__NLMSGERR_ATTR_MAX: number of attributes
|
||||
* @NLMSGERR_ATTR_MAX: highest attribute number
|
||||
*/
|
||||
enum nlmsgerr_attrs {
|
||||
NLMSGERR_ATTR_UNUSED,
|
||||
NLMSGERR_ATTR_MSG,
|
||||
NLMSGERR_ATTR_OFFS,
|
||||
NLMSGERR_ATTR_COOKIE,
|
||||
|
||||
__NLMSGERR_ATTR_MAX,
|
||||
NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
|
||||
};
|
||||
|
||||
#define NETLINK_ADD_MEMBERSHIP 1
|
||||
|
@ -115,6 +150,7 @@ struct nlmsgerr {
|
|||
#define NETLINK_LISTEN_ALL_NSID 8
|
||||
#define NETLINK_LIST_MEMBERSHIPS 9
|
||||
#define NETLINK_CAP_ACK 10
|
||||
#define NETLINK_EXT_ACK 11
|
||||
|
||||
struct nl_pktinfo {
|
||||
__u32 group;
|
||||
|
|
|
@ -1402,7 +1402,7 @@ static void audit_receive_skb(struct sk_buff *skb)
|
|||
err = audit_receive_msg(skb, nlh);
|
||||
/* if err or if this message says it wants a response */
|
||||
if (err || (nlh->nlmsg_flags & NLM_F_ACK))
|
||||
netlink_ack(skb, nlh, err);
|
||||
netlink_ack(skb, nlh, err, NULL);
|
||||
|
||||
nlh = nlmsg_next(nlh, &len);
|
||||
}
|
||||
|
|
28
lib/nlattr.c
28
lib/nlattr.c
|
@ -112,6 +112,7 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
|
|||
* @len: length of attribute stream
|
||||
* @maxtype: maximum attribute type to be expected
|
||||
* @policy: validation policy
|
||||
* @extack: extended ACK report struct
|
||||
*
|
||||
* Validates all attributes in the specified attribute stream against the
|
||||
* specified policy. Attributes with a type exceeding maxtype will be
|
||||
|
@ -120,20 +121,23 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
|
|||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_validate(const struct nlattr *head, int len, int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct nlattr *nla;
|
||||
int rem, err;
|
||||
int rem;
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem) {
|
||||
err = validate_nla(nla, maxtype, policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
int err = validate_nla(nla, maxtype, policy);
|
||||
|
||||
if (err < 0) {
|
||||
if (extack)
|
||||
extack->bad_attr = nla;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(nla_validate);
|
||||
|
||||
|
@ -180,7 +184,8 @@ EXPORT_SYMBOL(nla_policy_len);
|
|||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
|
||||
int len, const struct nla_policy *policy)
|
||||
int len, const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct nlattr *nla;
|
||||
int rem, err;
|
||||
|
@ -193,8 +198,11 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
|
|||
if (type > 0 && type <= maxtype) {
|
||||
if (policy) {
|
||||
err = validate_nla(nla, maxtype, policy);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
if (extack)
|
||||
extack->bad_attr = nla;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
tb[type] = (struct nlattr *)nla;
|
||||
|
|
|
@ -35,7 +35,8 @@ static inline int vlan_validate_qos_map(struct nlattr *attr)
|
|||
{
|
||||
if (!attr)
|
||||
return 0;
|
||||
return nla_validate_nested(attr, IFLA_VLAN_QOS_MAX, vlan_map_policy);
|
||||
return nla_validate_nested(attr, IFLA_VLAN_QOS_MAX, vlan_map_policy,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
|
||||
|
|
|
@ -464,7 +464,8 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
struct net_device *dev;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*bpm), tb, MDBA_SET_ENTRY_MAX, NULL);
|
||||
err = nlmsg_parse(nlh, sizeof(*bpm), tb, MDBA_SET_ENTRY_MAX, NULL,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -748,8 +748,8 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags)
|
|||
|
||||
if (p && protinfo) {
|
||||
if (protinfo->nla_type & NLA_F_NESTED) {
|
||||
err = nla_parse_nested(tb, IFLA_BRPORT_MAX,
|
||||
protinfo, br_port_policy);
|
||||
err = nla_parse_nested(tb, IFLA_BRPORT_MAX, protinfo,
|
||||
br_port_policy, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -227,8 +227,8 @@ int br_parse_vlan_tunnel_info(struct nlattr *attr,
|
|||
|
||||
memset(tinfo, 0, sizeof(*tinfo));
|
||||
|
||||
err = nla_parse_nested(tb, IFLA_BRIDGE_VLAN_TUNNEL_MAX,
|
||||
attr, vlan_tunnel_policy);
|
||||
err = nla_parse_nested(tb, IFLA_BRIDGE_VLAN_TUNNEL_MAX, attr,
|
||||
vlan_tunnel_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -641,7 +641,7 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
|
|||
memset(mod, 0, sizeof(*mod));
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(struct rtcanmsg), tb, CGW_MAX,
|
||||
cgw_policy);
|
||||
cgw_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -386,7 +386,7 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
goto errout;
|
||||
}
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -580,7 +580,7 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
goto errout;
|
||||
}
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -209,7 +209,8 @@ static int bpf_parse_prog(struct nlattr *attr, struct bpf_lwt_prog *prog,
|
|||
int ret;
|
||||
u32 fd;
|
||||
|
||||
ret = nla_parse_nested(tb, LWT_BPF_PROG_MAX, attr, bpf_prog_policy);
|
||||
ret = nla_parse_nested(tb, LWT_BPF_PROG_MAX, attr, bpf_prog_policy,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -249,7 +250,7 @@ static int bpf_build_state(struct nlattr *nla,
|
|||
if (family != AF_INET && family != AF_INET6)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
ret = nla_parse_nested(tb, LWT_BPF_MAX, nla, bpf_nl_policy);
|
||||
ret = nla_parse_nested(tb, LWT_BPF_MAX, nla, bpf_nl_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1661,7 +1661,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
|
||||
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
|
@ -1946,7 +1946,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
int err, tidx;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX,
|
||||
nl_neightbl_policy);
|
||||
nl_neightbl_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -1984,7 +1984,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
int i, ifindex = 0;
|
||||
|
||||
err = nla_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS],
|
||||
nl_ntbl_parm_policy);
|
||||
nl_ntbl_parm_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout_tbl_lock;
|
||||
|
||||
|
@ -2275,7 +2275,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
|
|||
unsigned int flags = NLM_F_MULTI;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL);
|
||||
err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL, NULL);
|
||||
if (!err) {
|
||||
if (tb[NDA_IFINDEX])
|
||||
filter_idx = nla_get_u32(tb[NDA_IFINDEX]);
|
||||
|
|
|
@ -579,7 +579,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
int nsid, err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
|
||||
rtnl_net_policy);
|
||||
rtnl_net_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (!tb[NETNSA_NSID])
|
||||
|
@ -653,7 +653,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
int err, id;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
|
||||
rtnl_net_policy);
|
||||
rtnl_net_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (tb[NETNSA_PID])
|
||||
|
|
|
@ -1515,7 +1515,8 @@ static const struct rtnl_link_ops *linkinfo_to_kind_ops(const struct nlattr *nla
|
|||
const struct rtnl_link_ops *ops = NULL;
|
||||
struct nlattr *linfo[IFLA_INFO_MAX + 1];
|
||||
|
||||
if (nla_parse_nested(linfo, IFLA_INFO_MAX, nla, ifla_info_policy) < 0)
|
||||
if (nla_parse_nested(linfo, IFLA_INFO_MAX, nla,
|
||||
ifla_info_policy, NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
if (linfo[IFLA_INFO_KIND]) {
|
||||
|
@ -1592,8 +1593,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
|
||||
sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
|
||||
|
||||
if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
|
||||
|
||||
if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX,
|
||||
ifla_policy, NULL) >= 0) {
|
||||
if (tb[IFLA_EXT_MASK])
|
||||
ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
|
||||
|
||||
|
@ -1640,9 +1641,10 @@ out:
|
|||
return skb->len;
|
||||
}
|
||||
|
||||
int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len)
|
||||
int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
|
||||
struct netlink_ext_ack *exterr)
|
||||
{
|
||||
return nla_parse(tb, IFLA_MAX, head, len, ifla_policy);
|
||||
return nla_parse(tb, IFLA_MAX, head, len, ifla_policy, exterr);
|
||||
}
|
||||
EXPORT_SYMBOL(rtnl_nla_parse_ifla);
|
||||
|
||||
|
@ -2078,7 +2080,7 @@ static int do_setlink(const struct sk_buff *skb,
|
|||
goto errout;
|
||||
}
|
||||
err = nla_parse_nested(vfinfo, IFLA_VF_MAX, attr,
|
||||
ifla_vf_policy);
|
||||
ifla_vf_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
err = do_setvfinfo(dev, vfinfo);
|
||||
|
@ -2106,7 +2108,7 @@ static int do_setlink(const struct sk_buff *skb,
|
|||
goto errout;
|
||||
}
|
||||
err = nla_parse_nested(port, IFLA_PORT_MAX, attr,
|
||||
ifla_port_policy);
|
||||
ifla_port_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
if (!port[IFLA_PORT_VF]) {
|
||||
|
@ -2126,7 +2128,8 @@ static int do_setlink(const struct sk_buff *skb,
|
|||
struct nlattr *port[IFLA_PORT_MAX+1];
|
||||
|
||||
err = nla_parse_nested(port, IFLA_PORT_MAX,
|
||||
tb[IFLA_PORT_SELF], ifla_port_policy);
|
||||
tb[IFLA_PORT_SELF], ifla_port_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -2170,7 +2173,7 @@ static int do_setlink(const struct sk_buff *skb,
|
|||
u32 xdp_flags = 0;
|
||||
|
||||
err = nla_parse_nested(xdp, IFLA_XDP_MAX, tb[IFLA_XDP],
|
||||
ifla_xdp_policy);
|
||||
ifla_xdp_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -2219,7 +2222,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
struct nlattr *tb[IFLA_MAX+1];
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -2312,7 +2315,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
struct nlattr *tb[IFLA_MAX+1];
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -2441,7 +2444,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
#ifdef CONFIG_MODULES
|
||||
replay:
|
||||
#endif
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -2472,7 +2475,8 @@ replay:
|
|||
|
||||
if (tb[IFLA_LINKINFO]) {
|
||||
err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
|
||||
tb[IFLA_LINKINFO], ifla_info_policy);
|
||||
tb[IFLA_LINKINFO], ifla_info_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else
|
||||
|
@ -2497,7 +2501,7 @@ replay:
|
|||
if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
|
||||
err = nla_parse_nested(attr, ops->maxtype,
|
||||
linkinfo[IFLA_INFO_DATA],
|
||||
ops->policy);
|
||||
ops->policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
data = attr;
|
||||
|
@ -2515,7 +2519,8 @@ replay:
|
|||
err = nla_parse_nested(slave_attr,
|
||||
m_ops->slave_maxtype,
|
||||
linkinfo[IFLA_INFO_SLAVE_DATA],
|
||||
m_ops->slave_policy);
|
||||
m_ops->slave_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
slave_data = slave_attr;
|
||||
|
@ -2684,7 +2689,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh)
|
|||
int err;
|
||||
u32 ext_filter_mask = 0;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -2734,7 +2739,7 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ?
|
||||
sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
|
||||
|
||||
if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
|
||||
if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy, NULL) >= 0) {
|
||||
if (tb[IFLA_EXT_MASK])
|
||||
ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
|
||||
}
|
||||
|
@ -2965,7 +2970,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
u16 vid;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
|
||||
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -3068,7 +3073,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
|
||||
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -3203,8 +3208,8 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
int err = 0;
|
||||
int fidx = 0;
|
||||
|
||||
if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
|
||||
ifla_policy) == 0) {
|
||||
if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb,
|
||||
IFLA_MAX, ifla_policy, NULL) == 0) {
|
||||
if (tb[IFLA_MASTER])
|
||||
br_idx = nla_get_u32(tb[IFLA_MASTER]);
|
||||
}
|
||||
|
@ -4046,7 +4051,8 @@ out:
|
|||
|
||||
/* Process one rtnetlink message. */
|
||||
|
||||
static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
rtnl_doit_func doit;
|
||||
|
|
|
@ -238,7 +238,8 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -245,8 +245,7 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX,
|
||||
tb[DCB_ATTR_PFC_CFG],
|
||||
dcbnl_pfc_up_nest);
|
||||
tb[DCB_ATTR_PFC_CFG], dcbnl_pfc_up_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -304,7 +303,7 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP],
|
||||
dcbnl_cap_nest);
|
||||
dcbnl_cap_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -348,7 +347,7 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS],
|
||||
dcbnl_numtcs_nest);
|
||||
dcbnl_numtcs_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -393,7 +392,7 @@ static int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS],
|
||||
dcbnl_numtcs_nest);
|
||||
dcbnl_numtcs_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -452,7 +451,7 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EINVAL;
|
||||
|
||||
ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
|
||||
dcbnl_app_nest);
|
||||
dcbnl_app_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -520,7 +519,7 @@ static int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EINVAL;
|
||||
|
||||
ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
|
||||
dcbnl_app_nest);
|
||||
dcbnl_app_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -577,8 +576,8 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
!netdev->dcbnl_ops->getpgbwgcfgrx)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX,
|
||||
tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest);
|
||||
ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, tb[DCB_ATTR_PG_CFG],
|
||||
dcbnl_pg_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -597,8 +596,8 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
data = pg_tb[DCB_PG_ATTR_TC_ALL];
|
||||
else
|
||||
data = pg_tb[i];
|
||||
ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX,
|
||||
data, dcbnl_tc_param_nest);
|
||||
ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, data,
|
||||
dcbnl_tc_param_nest, NULL);
|
||||
if (ret)
|
||||
goto err_pg;
|
||||
|
||||
|
@ -735,8 +734,7 @@ static int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX,
|
||||
tb[DCB_ATTR_PFC_CFG],
|
||||
dcbnl_pfc_up_nest);
|
||||
tb[DCB_ATTR_PFC_CFG], dcbnl_pfc_up_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -791,8 +789,8 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
!netdev->dcbnl_ops->setpgbwgcfgrx)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX,
|
||||
tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest);
|
||||
ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, tb[DCB_ATTR_PG_CFG],
|
||||
dcbnl_pg_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -801,7 +799,7 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
continue;
|
||||
|
||||
ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX,
|
||||
pg_tb[i], dcbnl_tc_param_nest);
|
||||
pg_tb[i], dcbnl_tc_param_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -889,8 +887,8 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
!netdev->dcbnl_ops->getbcncfg)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX,
|
||||
tb[DCB_ATTR_BCN], dcbnl_bcn_nest);
|
||||
ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, tb[DCB_ATTR_BCN],
|
||||
dcbnl_bcn_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -948,9 +946,8 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
!netdev->dcbnl_ops->setbcnrp)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX,
|
||||
tb[DCB_ATTR_BCN],
|
||||
dcbnl_pfc_up_nest);
|
||||
ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, tb[DCB_ATTR_BCN],
|
||||
dcbnl_pfc_up_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1424,8 +1421,8 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
if (!tb[DCB_ATTR_IEEE])
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
|
||||
tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
|
||||
err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, tb[DCB_ATTR_IEEE],
|
||||
dcbnl_ieee_policy, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -1508,8 +1505,8 @@ static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
if (!tb[DCB_ATTR_IEEE])
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
|
||||
tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
|
||||
err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, tb[DCB_ATTR_IEEE],
|
||||
dcbnl_ieee_policy, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -1581,8 +1578,8 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
if (!tb[DCB_ATTR_FEATCFG])
|
||||
return -EINVAL;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG],
|
||||
dcbnl_featcfg_nest);
|
||||
ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX,
|
||||
tb[DCB_ATTR_FEATCFG], dcbnl_featcfg_nest, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1625,8 +1622,8 @@ static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh,
|
|||
if (!tb[DCB_ATTR_FEATCFG])
|
||||
return -EINVAL;
|
||||
|
||||
ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG],
|
||||
dcbnl_featcfg_nest);
|
||||
ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX,
|
||||
tb[DCB_ATTR_FEATCFG], dcbnl_featcfg_nest, NULL);
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
|
@ -1715,7 +1712,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
return -EPERM;
|
||||
|
||||
ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX,
|
||||
dcbnl_rtnl_policy);
|
||||
dcbnl_rtnl_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -581,7 +581,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (!net_eq(net, &init_net))
|
||||
goto errout;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -625,7 +625,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (!net_eq(net, &init_net))
|
||||
return -EINVAL;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -515,7 +515,8 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (!net_eq(net, &init_net))
|
||||
return -EINVAL;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -540,7 +541,8 @@ static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (!net_eq(net, &init_net))
|
||||
return -EINVAL;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1654,7 +1654,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
|
|||
if (!net_eq(net, &init_net))
|
||||
return -EINVAL;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_dn_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_dn_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ static unsigned int dnrmg_hook(void *priv,
|
|||
}
|
||||
|
||||
|
||||
#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
|
||||
#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err), NULL); return; } while (0)
|
||||
|
||||
static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
|
||||
{
|
||||
|
|
|
@ -350,7 +350,7 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info)
|
|||
return 0;
|
||||
|
||||
invalid:
|
||||
netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL);
|
||||
netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL);
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
|
@ -432,7 +432,7 @@ static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
|
|||
return 0;
|
||||
|
||||
invalid:
|
||||
netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL);
|
||||
netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL);
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
|
|
|
@ -249,8 +249,7 @@ nl802154_prepare_wpan_dev_dump(struct sk_buff *skb,
|
|||
if (!cb->args[0]) {
|
||||
err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl802154_fam.hdrsize,
|
||||
genl_family_attrbuf(&nl802154_fam),
|
||||
nl802154_fam.maxattr,
|
||||
nl802154_policy);
|
||||
nl802154_fam.maxattr, nl802154_policy, NULL);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
|
@ -562,8 +561,8 @@ static int nl802154_dump_wpan_phy_parse(struct sk_buff *skb,
|
|||
struct nl802154_dump_wpan_phy_state *state)
|
||||
{
|
||||
struct nlattr **tb = genl_family_attrbuf(&nl802154_fam);
|
||||
int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl802154_fam.hdrsize,
|
||||
tb, nl802154_fam.maxattr, nl802154_policy);
|
||||
int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl802154_fam.hdrsize, tb,
|
||||
nl802154_fam.maxattr, nl802154_policy, NULL);
|
||||
|
||||
/* TODO check if we can handle error here,
|
||||
* we have no backward compatibility
|
||||
|
@ -1308,7 +1307,7 @@ ieee802154_llsec_parse_dev_addr(struct nlattr *nla,
|
|||
struct nlattr *attrs[NL802154_DEV_ADDR_ATTR_MAX + 1];
|
||||
|
||||
if (!nla || nla_parse_nested(attrs, NL802154_DEV_ADDR_ATTR_MAX, nla,
|
||||
nl802154_dev_addr_policy))
|
||||
nl802154_dev_addr_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
if (!attrs[NL802154_DEV_ADDR_ATTR_PAN_ID] ||
|
||||
|
@ -1348,7 +1347,7 @@ ieee802154_llsec_parse_key_id(struct nlattr *nla,
|
|||
struct nlattr *attrs[NL802154_KEY_ID_ATTR_MAX + 1];
|
||||
|
||||
if (!nla || nla_parse_nested(attrs, NL802154_KEY_ID_ATTR_MAX, nla,
|
||||
nl802154_key_id_policy))
|
||||
nl802154_key_id_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
if (!attrs[NL802154_KEY_ID_ATTR_MODE])
|
||||
|
@ -1565,7 +1564,7 @@ static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX,
|
||||
info->attrs[NL802154_ATTR_SEC_KEY],
|
||||
nl802154_key_policy))
|
||||
nl802154_key_policy, info->extack))
|
||||
return -EINVAL;
|
||||
|
||||
if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] ||
|
||||
|
@ -1615,7 +1614,7 @@ static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX,
|
||||
info->attrs[NL802154_ATTR_SEC_KEY],
|
||||
nl802154_key_policy))
|
||||
nl802154_key_policy, info->extack))
|
||||
return -EINVAL;
|
||||
|
||||
if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
|
||||
|
@ -1729,8 +1728,8 @@ ieee802154_llsec_parse_device(struct nlattr *nla,
|
|||
{
|
||||
struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
|
||||
|
||||
if (!nla || nla_parse_nested(attrs, NL802154_DEV_ATTR_MAX, nla,
|
||||
nl802154_dev_policy))
|
||||
if (!nla || nla_parse_nested(attrs, NL802154_DEV_ATTR_MAX,
|
||||
nla, nl802154_dev_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
@ -1783,7 +1782,7 @@ static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
if (nla_parse_nested(attrs, NL802154_DEV_ATTR_MAX,
|
||||
info->attrs[NL802154_ATTR_SEC_DEVICE],
|
||||
nl802154_dev_policy))
|
||||
nl802154_dev_policy, info->extack))
|
||||
return -EINVAL;
|
||||
|
||||
if (!attrs[NL802154_DEV_ATTR_EXTENDED_ADDR])
|
||||
|
@ -1911,7 +1910,7 @@ static int nl802154_add_llsec_devkey(struct sk_buff *skb, struct genl_info *info
|
|||
if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
|
||||
nla_parse_nested(attrs, NL802154_DEVKEY_ATTR_MAX,
|
||||
info->attrs[NL802154_ATTR_SEC_DEVKEY],
|
||||
nl802154_devkey_policy) < 0)
|
||||
nl802154_devkey_policy, info->extack) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER] ||
|
||||
|
@ -1943,7 +1942,7 @@ static int nl802154_del_llsec_devkey(struct sk_buff *skb, struct genl_info *info
|
|||
|
||||
if (nla_parse_nested(attrs, NL802154_DEVKEY_ATTR_MAX,
|
||||
info->attrs[NL802154_ATTR_SEC_DEVKEY],
|
||||
nl802154_devkey_policy))
|
||||
nl802154_devkey_policy, info->extack))
|
||||
return -EINVAL;
|
||||
|
||||
if (!attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
|
||||
|
@ -2063,8 +2062,8 @@ llsec_parse_seclevel(struct nlattr *nla, struct ieee802154_llsec_seclevel *sl)
|
|||
{
|
||||
struct nlattr *attrs[NL802154_SECLEVEL_ATTR_MAX + 1];
|
||||
|
||||
if (!nla || nla_parse_nested(attrs, NL802154_SECLEVEL_ATTR_MAX, nla,
|
||||
nl802154_seclevel_policy))
|
||||
if (!nla || nla_parse_nested(attrs, NL802154_SECLEVEL_ATTR_MAX,
|
||||
nla, nl802154_seclevel_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
memset(sl, 0, sizeof(*sl));
|
||||
|
|
|
@ -582,7 +582,8 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
|
||||
ASSERT_RTNL();
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -752,7 +753,8 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
|
|||
struct in_device *in_dev;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -1717,7 +1719,7 @@ static int inet_validate_link_af(const struct net_device *dev,
|
|||
if (dev && !__in_dev_get_rtnl(dev))
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy);
|
||||
err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1745,7 +1747,7 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
|
|||
if (!in_dev)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
if (nla_parse_nested(tb, IFLA_INET_MAX, nla, NULL) < 0)
|
||||
if (nla_parse_nested(tb, IFLA_INET_MAX, nla, NULL, NULL) < 0)
|
||||
BUG();
|
||||
|
||||
if (tb[IFLA_INET_CONF]) {
|
||||
|
@ -1882,7 +1884,7 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
|
|||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
|
||||
devconf_ipv4_policy);
|
||||
devconf_ipv4_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -632,7 +632,8 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
|
|||
int err, remaining;
|
||||
struct rtmsg *rtm;
|
||||
|
||||
err = nlmsg_validate(nlh, sizeof(*rtm), RTA_MAX, rtm_ipv4_policy);
|
||||
err = nlmsg_validate(nlh, sizeof(*rtm), RTA_MAX, rtm_ipv4_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ static int ip_tun_build_state(struct nlattr *attr,
|
|||
struct nlattr *tb[LWTUNNEL_IP_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, LWTUNNEL_IP_MAX, attr, ip_tun_policy);
|
||||
err = nla_parse_nested(tb, LWTUNNEL_IP_MAX, attr, ip_tun_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -332,7 +332,8 @@ static int ip6_tun_build_state(struct nlattr *attr,
|
|||
struct nlattr *tb[LWTUNNEL_IP6_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, LWTUNNEL_IP6_MAX, attr, ip6_tun_policy);
|
||||
err = nla_parse_nested(tb, LWTUNNEL_IP6_MAX, attr, ip6_tun_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -2439,7 +2439,8 @@ static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh,
|
|||
struct rtmsg *rtm;
|
||||
int ret, rem;
|
||||
|
||||
ret = nlmsg_validate(nlh, sizeof(*rtm), RTA_MAX, rtm_ipmr_policy);
|
||||
ret = nlmsg_validate(nlh, sizeof(*rtm), RTA_MAX, rtm_ipmr_policy,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
rtm = nlmsg_data(nlh);
|
||||
|
|
|
@ -2645,7 +2645,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
|
|||
u32 table_id = RT_TABLE_MAIN;
|
||||
kuid_t uid;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -624,7 +624,7 @@ static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
|
|||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
|
||||
devconf_ipv6_policy);
|
||||
devconf_ipv6_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -4408,7 +4408,8 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
u32 ifa_flags;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -4520,7 +4521,8 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
u32 ifa_flags;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -4881,7 +4883,8 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh)
|
|||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -5251,7 +5254,8 @@ static int inet6_validate_link_af(const struct net_device *dev,
|
|||
if (dev && !__in6_dev_get(dev))
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
return nla_parse_nested(tb, IFLA_INET6_MAX, nla, inet6_af_policy);
|
||||
return nla_parse_nested(tb, IFLA_INET6_MAX, nla, inet6_af_policy,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int check_addr_gen_mode(int mode)
|
||||
|
@ -5283,7 +5287,7 @@ static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
|
|||
if (!idev)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
if (nla_parse_nested(tb, IFLA_INET6_MAX, nla, NULL) < 0)
|
||||
if (nla_parse_nested(tb, IFLA_INET6_MAX, nla, NULL, NULL) < 0)
|
||||
BUG();
|
||||
|
||||
if (tb[IFLA_INET6_TOKEN]) {
|
||||
|
|
|
@ -413,7 +413,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
u32 label;
|
||||
int err = 0;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -532,7 +532,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh)
|
|||
struct ip6addrlbl_entry *p;
|
||||
struct sk_buff *skb;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -146,8 +146,7 @@ static int ila_build_state(struct nlattr *nla,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla,
|
||||
ila_nl_policy);
|
||||
ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -2906,7 +2906,8 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
unsigned int pref;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -3574,7 +3575,8 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
|
|||
struct flowi6 fl6;
|
||||
int err, iif = 0, oif = 0;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ static int seg6_build_state(struct nlattr *nla,
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, SEG6_IPTUNNEL_MAX, nla,
|
||||
seg6_iptunnel_policy);
|
||||
seg6_iptunnel_policy, NULL);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
|
@ -1122,7 +1122,7 @@ static int mpls_netconf_get_devconf(struct sk_buff *in_skb,
|
|||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
|
||||
devconf_mpls_policy);
|
||||
devconf_mpls_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
@ -1643,7 +1643,8 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
int index;
|
||||
int err;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_mpls_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_mpls_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ static int mpls_build_state(struct nlattr *nla,
|
|||
int ret;
|
||||
|
||||
ret = nla_parse_nested(tb, MPLS_IPTUNNEL_MAX, nla,
|
||||
mpls_iptunnel_policy);
|
||||
mpls_iptunnel_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -295,7 +295,8 @@ ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr)
|
|||
|
||||
if (unlikely(!flag_nested(nla)))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla, ipaddr_policy))
|
||||
if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla,
|
||||
ipaddr_policy, NULL))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV4)))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
|
@ -313,7 +314,8 @@ ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr)
|
|||
if (unlikely(!flag_nested(nla)))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
|
||||
if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla, ipaddr_policy))
|
||||
if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla,
|
||||
ipaddr_policy, NULL))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV6)))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
|
@ -906,7 +908,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl,
|
|||
/* Without holding any locks, create private part. */
|
||||
if (attr[IPSET_ATTR_DATA] &&
|
||||
nla_parse_nested(tb, IPSET_ATTR_CREATE_MAX, attr[IPSET_ATTR_DATA],
|
||||
set->type->create_policy)) {
|
||||
set->type->create_policy, NULL)) {
|
||||
ret = -IPSET_ERR_PROTOCOL;
|
||||
goto put_out;
|
||||
}
|
||||
|
@ -1257,8 +1259,8 @@ dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
|
|||
ip_set_id_t index;
|
||||
|
||||
/* Second pass, so parser can't fail */
|
||||
nla_parse(cda, IPSET_ATTR_CMD_MAX,
|
||||
attr, nlh->nlmsg_len - min_len, ip_set_setname_policy);
|
||||
nla_parse(cda, IPSET_ATTR_CMD_MAX, attr, nlh->nlmsg_len - min_len,
|
||||
ip_set_setname_policy, NULL);
|
||||
|
||||
if (cda[IPSET_ATTR_SETNAME]) {
|
||||
struct ip_set *set;
|
||||
|
@ -1305,7 +1307,7 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
* manually :-(
|
||||
*/
|
||||
if (nlh->nlmsg_flags & NLM_F_ACK)
|
||||
netlink_ack(cb->skb, nlh, ret);
|
||||
netlink_ack(cb->skb, nlh, ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -1501,9 +1503,8 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
|
|||
memcpy(&errmsg->msg, nlh, nlh->nlmsg_len);
|
||||
cmdattr = (void *)&errmsg->msg + min_len;
|
||||
|
||||
nla_parse(cda, IPSET_ATTR_CMD_MAX,
|
||||
cmdattr, nlh->nlmsg_len - min_len,
|
||||
ip_set_adt_policy);
|
||||
nla_parse(cda, IPSET_ATTR_CMD_MAX, cmdattr,
|
||||
nlh->nlmsg_len - min_len, ip_set_adt_policy, NULL);
|
||||
|
||||
errline = nla_data(cda[IPSET_ATTR_LINENO]);
|
||||
|
||||
|
@ -1549,7 +1550,7 @@ static int ip_set_uadd(struct net *net, struct sock *ctnl, struct sk_buff *skb,
|
|||
if (attr[IPSET_ATTR_DATA]) {
|
||||
if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX,
|
||||
attr[IPSET_ATTR_DATA],
|
||||
set->type->adt_policy))
|
||||
set->type->adt_policy, NULL))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
ret = call_ad(ctnl, skb, set, tb, IPSET_ADD, flags,
|
||||
use_lineno);
|
||||
|
@ -1561,7 +1562,7 @@ static int ip_set_uadd(struct net *net, struct sock *ctnl, struct sk_buff *skb,
|
|||
if (nla_type(nla) != IPSET_ATTR_DATA ||
|
||||
!flag_nested(nla) ||
|
||||
nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, nla,
|
||||
set->type->adt_policy))
|
||||
set->type->adt_policy, NULL))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
ret = call_ad(ctnl, skb, set, tb, IPSET_ADD,
|
||||
flags, use_lineno);
|
||||
|
@ -1603,7 +1604,7 @@ static int ip_set_udel(struct net *net, struct sock *ctnl, struct sk_buff *skb,
|
|||
if (attr[IPSET_ATTR_DATA]) {
|
||||
if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX,
|
||||
attr[IPSET_ATTR_DATA],
|
||||
set->type->adt_policy))
|
||||
set->type->adt_policy, NULL))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
ret = call_ad(ctnl, skb, set, tb, IPSET_DEL, flags,
|
||||
use_lineno);
|
||||
|
@ -1615,7 +1616,7 @@ static int ip_set_udel(struct net *net, struct sock *ctnl, struct sk_buff *skb,
|
|||
if (nla_type(nla) != IPSET_ATTR_DATA ||
|
||||
!flag_nested(nla) ||
|
||||
nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, nla,
|
||||
set->type->adt_policy))
|
||||
set->type->adt_policy, NULL))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
ret = call_ad(ctnl, skb, set, tb, IPSET_DEL,
|
||||
flags, use_lineno);
|
||||
|
@ -1646,7 +1647,7 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
|
|||
return -ENOENT;
|
||||
|
||||
if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, attr[IPSET_ATTR_DATA],
|
||||
set->type->adt_policy))
|
||||
set->type->adt_policy, NULL))
|
||||
return -IPSET_ERR_PROTOCOL;
|
||||
|
||||
rcu_read_lock_bh();
|
||||
|
|
|
@ -3089,7 +3089,8 @@ static int ip_vs_genl_parse_service(struct netns_ipvs *ipvs,
|
|||
|
||||
/* Parse mandatory identifying service fields first */
|
||||
if (nla == NULL ||
|
||||
nla_parse_nested(attrs, IPVS_SVC_ATTR_MAX, nla, ip_vs_svc_policy))
|
||||
nla_parse_nested(attrs, IPVS_SVC_ATTR_MAX, nla,
|
||||
ip_vs_svc_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
nla_af = attrs[IPVS_SVC_ATTR_AF];
|
||||
|
@ -3251,8 +3252,8 @@ static int ip_vs_genl_dump_dests(struct sk_buff *skb,
|
|||
mutex_lock(&__ip_vs_mutex);
|
||||
|
||||
/* Try to find the service for which to dump destinations */
|
||||
if (nlmsg_parse(cb->nlh, GENL_HDRLEN, attrs,
|
||||
IPVS_CMD_ATTR_MAX, ip_vs_cmd_policy))
|
||||
if (nlmsg_parse(cb->nlh, GENL_HDRLEN, attrs, IPVS_CMD_ATTR_MAX,
|
||||
ip_vs_cmd_policy, NULL))
|
||||
goto out_err;
|
||||
|
||||
|
||||
|
@ -3288,7 +3289,8 @@ static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest,
|
|||
|
||||
/* Parse mandatory identifying destination fields first */
|
||||
if (nla == NULL ||
|
||||
nla_parse_nested(attrs, IPVS_DEST_ATTR_MAX, nla, ip_vs_dest_policy))
|
||||
nla_parse_nested(attrs, IPVS_DEST_ATTR_MAX, nla,
|
||||
ip_vs_dest_policy, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
nla_addr = attrs[IPVS_DEST_ATTR_ADDR];
|
||||
|
@ -3530,7 +3532,7 @@ static int ip_vs_genl_set_daemon(struct sk_buff *skb, struct genl_info *info)
|
|||
if (!info->attrs[IPVS_CMD_ATTR_DAEMON] ||
|
||||
nla_parse_nested(daemon_attrs, IPVS_DAEMON_ATTR_MAX,
|
||||
info->attrs[IPVS_CMD_ATTR_DAEMON],
|
||||
ip_vs_daemon_policy))
|
||||
ip_vs_daemon_policy, info->extack))
|
||||
goto out;
|
||||
|
||||
if (cmd == IPVS_CMD_NEW_DAEMON)
|
||||
|
|
|
@ -908,7 +908,7 @@ static int ctnetlink_parse_tuple_ip(struct nlattr *attr,
|
|||
struct nf_conntrack_l3proto *l3proto;
|
||||
int ret = 0;
|
||||
|
||||
ret = nla_parse_nested(tb, CTA_IP_MAX, attr, NULL);
|
||||
ret = nla_parse_nested(tb, CTA_IP_MAX, attr, NULL, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -917,7 +917,7 @@ static int ctnetlink_parse_tuple_ip(struct nlattr *attr,
|
|||
|
||||
if (likely(l3proto->nlattr_to_tuple)) {
|
||||
ret = nla_validate_nested(attr, CTA_IP_MAX,
|
||||
l3proto->nla_policy);
|
||||
l3proto->nla_policy, NULL);
|
||||
if (ret == 0)
|
||||
ret = l3proto->nlattr_to_tuple(tb, tuple);
|
||||
}
|
||||
|
@ -938,7 +938,8 @@ static int ctnetlink_parse_tuple_proto(struct nlattr *attr,
|
|||
struct nf_conntrack_l4proto *l4proto;
|
||||
int ret = 0;
|
||||
|
||||
ret = nla_parse_nested(tb, CTA_PROTO_MAX, attr, proto_nla_policy);
|
||||
ret = nla_parse_nested(tb, CTA_PROTO_MAX, attr, proto_nla_policy,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -951,7 +952,7 @@ static int ctnetlink_parse_tuple_proto(struct nlattr *attr,
|
|||
|
||||
if (likely(l4proto->nlattr_to_tuple)) {
|
||||
ret = nla_validate_nested(attr, CTA_PROTO_MAX,
|
||||
l4proto->nla_policy);
|
||||
l4proto->nla_policy, NULL);
|
||||
if (ret == 0)
|
||||
ret = l4proto->nlattr_to_tuple(tb, tuple);
|
||||
}
|
||||
|
@ -1015,7 +1016,8 @@ ctnetlink_parse_tuple(const struct nlattr * const cda[],
|
|||
|
||||
memset(tuple, 0, sizeof(*tuple));
|
||||
|
||||
err = nla_parse_nested(tb, CTA_TUPLE_MAX, cda[type], tuple_nla_policy);
|
||||
err = nla_parse_nested(tb, CTA_TUPLE_MAX, cda[type], tuple_nla_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1065,7 +1067,7 @@ static int ctnetlink_parse_help(const struct nlattr *attr, char **helper_name,
|
|||
int err;
|
||||
struct nlattr *tb[CTA_HELP_MAX+1];
|
||||
|
||||
err = nla_parse_nested(tb, CTA_HELP_MAX, attr, help_nla_policy);
|
||||
err = nla_parse_nested(tb, CTA_HELP_MAX, attr, help_nla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1566,7 +1568,8 @@ static int ctnetlink_change_protoinfo(struct nf_conn *ct,
|
|||
struct nf_conntrack_l4proto *l4proto;
|
||||
int err = 0;
|
||||
|
||||
err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, protoinfo_policy);
|
||||
err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, protoinfo_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1591,7 +1594,7 @@ static int change_seq_adj(struct nf_ct_seqadj *seq,
|
|||
int err;
|
||||
struct nlattr *cda[CTA_SEQADJ_MAX+1];
|
||||
|
||||
err = nla_parse_nested(cda, CTA_SEQADJ_MAX, attr, seqadj_policy);
|
||||
err = nla_parse_nested(cda, CTA_SEQADJ_MAX, attr, seqadj_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -2348,7 +2351,7 @@ ctnetlink_glue_parse(const struct nlattr *attr, struct nf_conn *ct)
|
|||
struct nlattr *cda[CTA_MAX+1];
|
||||
int ret;
|
||||
|
||||
ret = nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy);
|
||||
ret = nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -2385,7 +2388,8 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
|
|||
struct nf_conntrack_expect *exp;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(cda, CTA_EXPECT_MAX, attr, exp_nla_policy);
|
||||
err = nla_parse_nested(cda, CTA_EXPECT_MAX, attr, exp_nla_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -3004,7 +3008,8 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr,
|
|||
struct nf_conntrack_tuple nat_tuple = {};
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_nla_policy);
|
||||
err = nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr,
|
||||
exp_nat_nla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -665,7 +665,7 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
|
|||
return 0;
|
||||
|
||||
err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
|
||||
dccp_nla_policy);
|
||||
dccp_nla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -584,10 +584,8 @@ static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
|
|||
if (!attr)
|
||||
return 0;
|
||||
|
||||
err = nla_parse_nested(tb,
|
||||
CTA_PROTOINFO_SCTP_MAX,
|
||||
attr,
|
||||
sctp_nla_policy);
|
||||
err = nla_parse_nested(tb, CTA_PROTOINFO_SCTP_MAX, attr,
|
||||
sctp_nla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1234,7 +1234,8 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
|
|||
if (!pattr)
|
||||
return 0;
|
||||
|
||||
err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr, tcp_nla_policy);
|
||||
err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr,
|
||||
tcp_nla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -751,7 +751,8 @@ static int nfnetlink_parse_nat_proto(struct nlattr *attr,
|
|||
const struct nf_nat_l4proto *l4proto;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
|
||||
err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr,
|
||||
protonat_nla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -780,7 +781,7 @@ nfnetlink_parse_nat(const struct nlattr *nat,
|
|||
|
||||
memset(range, 0, sizeof(*range));
|
||||
|
||||
err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
|
||||
err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1182,7 +1182,8 @@ static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
|
|||
struct nft_stats *stats;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFTA_COUNTER_MAX, attr, nft_counter_policy);
|
||||
err = nla_parse_nested(tb, NFTA_COUNTER_MAX, attr, nft_counter_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
|
@ -1257,7 +1258,7 @@ static int nft_chain_parse_hook(struct net *net,
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
|
||||
nft_hook_policy);
|
||||
nft_hook_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1724,7 +1725,7 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx,
|
|||
struct nlattr *tb[NFTA_EXPR_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFTA_EXPR_MAX, nla, nft_expr_policy);
|
||||
err = nla_parse_nested(tb, NFTA_EXPR_MAX, nla, nft_expr_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1734,7 +1735,7 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx,
|
|||
|
||||
if (tb[NFTA_EXPR_DATA]) {
|
||||
err = nla_parse_nested(info->tb, type->maxattr,
|
||||
tb[NFTA_EXPR_DATA], type->policy);
|
||||
tb[NFTA_EXPR_DATA], type->policy, NULL);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
} else
|
||||
|
@ -2879,7 +2880,8 @@ static int nf_tables_set_desc_parse(const struct nft_ctx *ctx,
|
|||
struct nlattr *da[NFTA_SET_DESC_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(da, NFTA_SET_DESC_MAX, nla, nft_set_desc_policy);
|
||||
err = nla_parse_nested(da, NFTA_SET_DESC_MAX, nla,
|
||||
nft_set_desc_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -3381,7 +3383,8 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
int event, err;
|
||||
|
||||
err = nlmsg_parse(cb->nlh, sizeof(struct nfgenmsg), nla,
|
||||
NFTA_SET_ELEM_LIST_MAX, nft_set_elem_list_policy);
|
||||
NFTA_SET_ELEM_LIST_MAX, nft_set_elem_list_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -3640,7 +3643,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
|
||||
nft_set_elem_policy);
|
||||
nft_set_elem_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -3870,7 +3873,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
|
||||
nft_set_elem_policy);
|
||||
nft_set_elem_policy, NULL);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
|
@ -4101,7 +4104,8 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,
|
|||
int err;
|
||||
|
||||
if (attr) {
|
||||
err = nla_parse_nested(tb, type->maxattr, attr, type->policy);
|
||||
err = nla_parse_nested(tb, type->maxattr, attr, type->policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
} else {
|
||||
|
@ -5314,7 +5318,8 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
|
|||
struct nft_chain *chain;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy);
|
||||
err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -5444,7 +5449,7 @@ int nft_data_init(const struct nft_ctx *ctx,
|
|||
struct nlattr *tb[NFTA_DATA_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy);
|
||||
err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -148,7 +148,8 @@ int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u32 portid,
|
|||
EXPORT_SYMBOL_GPL(nfnetlink_unicast);
|
||||
|
||||
/* Process one complete nfnetlink message. */
|
||||
static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
const struct nfnl_callback *nc;
|
||||
|
@ -191,8 +192,8 @@ replay:
|
|||
int attrlen = nlh->nlmsg_len - min_len;
|
||||
__u8 subsys_id = NFNL_SUBSYS_ID(type);
|
||||
|
||||
err = nla_parse(cda, ss->cb[cb_id].attr_count,
|
||||
attr, attrlen, ss->cb[cb_id].policy);
|
||||
err = nla_parse(cda, ss->cb[cb_id].attr_count, attr, attrlen,
|
||||
ss->cb[cb_id].policy, extack);
|
||||
if (err < 0) {
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
|
@ -261,7 +262,7 @@ static void nfnl_err_deliver(struct list_head *err_list, struct sk_buff *skb)
|
|||
struct nfnl_err *nfnl_err, *next;
|
||||
|
||||
list_for_each_entry_safe(nfnl_err, next, err_list, head) {
|
||||
netlink_ack(skb, nfnl_err->nlh, nfnl_err->err);
|
||||
netlink_ack(skb, nfnl_err->nlh, nfnl_err->err, NULL);
|
||||
nfnl_err_del(nfnl_err);
|
||||
}
|
||||
}
|
||||
|
@ -284,13 +285,13 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
int err;
|
||||
|
||||
if (subsys_id >= NFNL_SUBSYS_COUNT)
|
||||
return netlink_ack(skb, nlh, -EINVAL);
|
||||
return netlink_ack(skb, nlh, -EINVAL, NULL);
|
||||
replay:
|
||||
status = 0;
|
||||
|
||||
skb = netlink_skb_clone(oskb, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return netlink_ack(oskb, nlh, -ENOMEM);
|
||||
return netlink_ack(oskb, nlh, -ENOMEM, NULL);
|
||||
|
||||
nfnl_lock(subsys_id);
|
||||
ss = nfnl_dereference_protected(subsys_id);
|
||||
|
@ -304,20 +305,20 @@ replay:
|
|||
#endif
|
||||
{
|
||||
nfnl_unlock(subsys_id);
|
||||
netlink_ack(oskb, nlh, -EOPNOTSUPP);
|
||||
netlink_ack(oskb, nlh, -EOPNOTSUPP, NULL);
|
||||
return kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ss->commit || !ss->abort) {
|
||||
nfnl_unlock(subsys_id);
|
||||
netlink_ack(oskb, nlh, -EOPNOTSUPP);
|
||||
netlink_ack(oskb, nlh, -EOPNOTSUPP, NULL);
|
||||
return kfree_skb(skb);
|
||||
}
|
||||
|
||||
if (genid && ss->valid_genid && !ss->valid_genid(net, genid)) {
|
||||
nfnl_unlock(subsys_id);
|
||||
netlink_ack(oskb, nlh, -ERESTART);
|
||||
netlink_ack(oskb, nlh, -ERESTART, NULL);
|
||||
return kfree_skb(skb);
|
||||
}
|
||||
|
||||
|
@ -376,8 +377,8 @@ replay:
|
|||
struct nlattr *attr = (void *)nlh + min_len;
|
||||
int attrlen = nlh->nlmsg_len - min_len;
|
||||
|
||||
err = nla_parse(cda, ss->cb[cb_id].attr_count,
|
||||
attr, attrlen, ss->cb[cb_id].policy);
|
||||
err = nla_parse(cda, ss->cb[cb_id].attr_count, attr,
|
||||
attrlen, ss->cb[cb_id].policy, NULL);
|
||||
if (err < 0)
|
||||
goto ack;
|
||||
|
||||
|
@ -407,7 +408,8 @@ ack:
|
|||
* pointing to the batch header.
|
||||
*/
|
||||
nfnl_err_reset(&err_list);
|
||||
netlink_ack(oskb, nlmsg_hdr(oskb), -ENOMEM);
|
||||
netlink_ack(oskb, nlmsg_hdr(oskb), -ENOMEM,
|
||||
NULL);
|
||||
status |= NFNL_BATCH_FAILURE;
|
||||
goto done;
|
||||
}
|
||||
|
@ -465,9 +467,10 @@ static void nfnetlink_rcv_skb_batch(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
skb->len < NLMSG_HDRLEN + sizeof(struct nfgenmsg))
|
||||
return;
|
||||
|
||||
err = nla_parse(cda, NFNL_BATCH_MAX, attr, attrlen, nfnl_batch_policy);
|
||||
err = nla_parse(cda, NFNL_BATCH_MAX, attr, attrlen, nfnl_batch_policy,
|
||||
NULL);
|
||||
if (err < 0) {
|
||||
netlink_ack(skb, nlh, err);
|
||||
netlink_ack(skb, nlh, err, NULL);
|
||||
return;
|
||||
}
|
||||
if (cda[NFNL_BATCH_GENID])
|
||||
|
@ -493,7 +496,7 @@ static void nfnetlink_rcv(struct sk_buff *skb)
|
|||
return;
|
||||
|
||||
if (!netlink_net_capable(skb, CAP_NET_ADMIN)) {
|
||||
netlink_ack(skb, nlh, -EPERM);
|
||||
netlink_ack(skb, nlh, -EPERM, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,8 @@ nfacct_filter_alloc(const struct nlattr * const attr)
|
|||
struct nlattr *tb[NFACCT_FILTER_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFACCT_FILTER_MAX, attr, filter_policy);
|
||||
err = nla_parse_nested(tb, NFACCT_FILTER_MAX, attr, filter_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
|
|
|
@ -77,7 +77,8 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple,
|
|||
int err;
|
||||
struct nlattr *tb[NFCTH_TUPLE_MAX+1];
|
||||
|
||||
err = nla_parse_nested(tb, NFCTH_TUPLE_MAX, attr, nfnl_cthelper_tuple_pol);
|
||||
err = nla_parse_nested(tb, NFCTH_TUPLE_MAX, attr,
|
||||
nfnl_cthelper_tuple_pol, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -137,7 +138,8 @@ nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy,
|
|||
int err;
|
||||
struct nlattr *tb[NFCTH_POLICY_MAX+1];
|
||||
|
||||
err = nla_parse_nested(tb, NFCTH_POLICY_MAX, attr, nfnl_cthelper_expect_pol);
|
||||
err = nla_parse_nested(tb, NFCTH_POLICY_MAX, attr,
|
||||
nfnl_cthelper_expect_pol, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -171,7 +173,7 @@ nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper,
|
|||
unsigned int class_max;
|
||||
|
||||
ret = nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr,
|
||||
nfnl_cthelper_expect_policy_set);
|
||||
nfnl_cthelper_expect_policy_set, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -276,7 +278,7 @@ nfnl_cthelper_update_policy_one(const struct nf_conntrack_expect_policy *policy,
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFCTH_POLICY_MAX, attr,
|
||||
nfnl_cthelper_expect_pol);
|
||||
nfnl_cthelper_expect_pol, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -336,7 +338,7 @@ static int nfnl_cthelper_update_policy(struct nf_conntrack_helper *helper,
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr,
|
||||
nfnl_cthelper_expect_policy_set);
|
||||
nfnl_cthelper_expect_policy_set, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ ctnl_timeout_parse_policy(void *timeouts, struct nf_conntrack_l4proto *l4proto,
|
|||
struct nlattr *tb[l4proto->ctnl_timeout.nlattr_max+1];
|
||||
|
||||
ret = nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max,
|
||||
attr, l4proto->ctnl_timeout.nla_policy);
|
||||
attr, l4proto->ctnl_timeout.nla_policy,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1109,7 +1109,7 @@ static int nfqa_parse_bridge(struct nf_queue_entry *entry,
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFQA_VLAN_MAX, nfqa[NFQA_VLAN],
|
||||
nfqa_vlan_policy);
|
||||
nfqa_vlan_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
|
|||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFTA_RULE_COMPAT_MAX, attr,
|
||||
nft_rule_compat_policy);
|
||||
nft_rule_compat_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
|
|||
|
||||
if (nla_validate_nested(info->attrs[NLBL_CIPSOV4_A_TAGLST],
|
||||
NLBL_CIPSOV4_A_MAX,
|
||||
netlbl_cipsov4_genl_policy) != 0)
|
||||
netlbl_cipsov4_genl_policy, NULL) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem)
|
||||
|
@ -148,7 +148,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info,
|
|||
|
||||
if (nla_validate_nested(info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
|
||||
NLBL_CIPSOV4_A_MAX,
|
||||
netlbl_cipsov4_genl_policy) != 0)
|
||||
netlbl_cipsov4_genl_policy, NULL) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
|
||||
|
@ -170,10 +170,10 @@ static int netlbl_cipsov4_add_std(struct genl_info *info,
|
|||
info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
|
||||
nla_a_rem)
|
||||
if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
|
||||
if (nla_validate_nested(nla_a,
|
||||
NLBL_CIPSOV4_A_MAX,
|
||||
netlbl_cipsov4_genl_policy) != 0)
|
||||
goto add_std_failure;
|
||||
if (nla_validate_nested(nla_a, NLBL_CIPSOV4_A_MAX,
|
||||
netlbl_cipsov4_genl_policy,
|
||||
NULL) != 0)
|
||||
goto add_std_failure;
|
||||
nla_for_each_nested(nla_b, nla_a, nla_b_rem)
|
||||
switch (nla_type(nla_b)) {
|
||||
case NLBL_CIPSOV4_A_MLSLVLLOC:
|
||||
|
@ -236,7 +236,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info,
|
|||
if (info->attrs[NLBL_CIPSOV4_A_MLSCATLST]) {
|
||||
if (nla_validate_nested(info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
|
||||
NLBL_CIPSOV4_A_MAX,
|
||||
netlbl_cipsov4_genl_policy) != 0)
|
||||
netlbl_cipsov4_genl_policy, NULL) != 0)
|
||||
goto add_std_failure;
|
||||
|
||||
nla_for_each_nested(nla_a,
|
||||
|
@ -244,8 +244,9 @@ static int netlbl_cipsov4_add_std(struct genl_info *info,
|
|||
nla_a_rem)
|
||||
if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
|
||||
if (nla_validate_nested(nla_a,
|
||||
NLBL_CIPSOV4_A_MAX,
|
||||
netlbl_cipsov4_genl_policy) != 0)
|
||||
NLBL_CIPSOV4_A_MAX,
|
||||
netlbl_cipsov4_genl_policy,
|
||||
NULL) != 0)
|
||||
goto add_std_failure;
|
||||
nla_for_each_nested(nla_b, nla_a, nla_b_rem)
|
||||
switch (nla_type(nla_b)) {
|
||||
|
|
|
@ -1652,6 +1652,13 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
|||
nlk->flags &= ~NETLINK_F_CAP_ACK;
|
||||
err = 0;
|
||||
break;
|
||||
case NETLINK_EXT_ACK:
|
||||
if (val)
|
||||
nlk->flags |= NETLINK_F_EXT_ACK;
|
||||
else
|
||||
nlk->flags &= ~NETLINK_F_EXT_ACK;
|
||||
err = 0;
|
||||
break;
|
||||
default:
|
||||
err = -ENOPROTOOPT;
|
||||
}
|
||||
|
@ -1736,6 +1743,15 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
|
|||
return -EFAULT;
|
||||
err = 0;
|
||||
break;
|
||||
case NETLINK_EXT_ACK:
|
||||
if (len < sizeof(int))
|
||||
return -EINVAL;
|
||||
len = sizeof(int);
|
||||
val = nlk->flags & NETLINK_F_EXT_ACK ? 1 : 0;
|
||||
if (put_user(len, optlen) || put_user(val, optval))
|
||||
return -EFAULT;
|
||||
err = 0;
|
||||
break;
|
||||
default:
|
||||
err = -ENOPROTOOPT;
|
||||
}
|
||||
|
@ -2267,21 +2283,44 @@ error_free:
|
|||
}
|
||||
EXPORT_SYMBOL(__netlink_dump_start);
|
||||
|
||||
void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
|
||||
void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
|
||||
const struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct nlmsghdr *rep;
|
||||
struct nlmsgerr *errmsg;
|
||||
size_t payload = sizeof(*errmsg);
|
||||
size_t tlvlen = 0;
|
||||
struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
|
||||
unsigned int flags = 0;
|
||||
|
||||
/* Error messages get the original request appened, unless the user
|
||||
* requests to cap the error message.
|
||||
* requests to cap the error message, and get extra error data if
|
||||
* requested.
|
||||
*/
|
||||
if (!(nlk->flags & NETLINK_F_CAP_ACK) && err)
|
||||
payload += nlmsg_len(nlh);
|
||||
if (err) {
|
||||
if (!(nlk->flags & NETLINK_F_CAP_ACK))
|
||||
payload += nlmsg_len(nlh);
|
||||
else
|
||||
flags |= NLM_F_CAPPED;
|
||||
if (nlk->flags & NETLINK_F_EXT_ACK && extack) {
|
||||
if (extack->_msg)
|
||||
tlvlen += nla_total_size(strlen(extack->_msg) + 1);
|
||||
if (extack->bad_attr)
|
||||
tlvlen += nla_total_size(sizeof(u32));
|
||||
}
|
||||
} else {
|
||||
flags |= NLM_F_CAPPED;
|
||||
|
||||
skb = nlmsg_new(payload, GFP_KERNEL);
|
||||
if (nlk->flags & NETLINK_F_EXT_ACK &&
|
||||
extack && extack->cookie_len)
|
||||
tlvlen += nla_total_size(extack->cookie_len);
|
||||
}
|
||||
|
||||
if (tlvlen)
|
||||
flags |= NLM_F_ACK_TLVS;
|
||||
|
||||
skb = nlmsg_new(payload + tlvlen, GFP_KERNEL);
|
||||
if (!skb) {
|
||||
struct sock *sk;
|
||||
|
||||
|
@ -2297,17 +2336,42 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
|
|||
}
|
||||
|
||||
rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
|
||||
NLMSG_ERROR, payload, 0);
|
||||
NLMSG_ERROR, payload, flags);
|
||||
errmsg = nlmsg_data(rep);
|
||||
errmsg->error = err;
|
||||
memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
|
||||
|
||||
if (nlk->flags & NETLINK_F_EXT_ACK && extack) {
|
||||
if (err) {
|
||||
if (extack->_msg)
|
||||
WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
|
||||
extack->_msg));
|
||||
if (extack->bad_attr &&
|
||||
!WARN_ON((u8 *)extack->bad_attr < in_skb->data ||
|
||||
(u8 *)extack->bad_attr >= in_skb->data +
|
||||
in_skb->len))
|
||||
WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
|
||||
(u8 *)extack->bad_attr -
|
||||
in_skb->data));
|
||||
} else {
|
||||
if (extack->cookie_len)
|
||||
WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE,
|
||||
extack->cookie_len,
|
||||
extack->cookie));
|
||||
}
|
||||
}
|
||||
|
||||
nlmsg_end(skb, rep);
|
||||
|
||||
netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid, MSG_DONTWAIT);
|
||||
}
|
||||
EXPORT_SYMBOL(netlink_ack);
|
||||
|
||||
int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
|
||||
struct nlmsghdr *))
|
||||
struct nlmsghdr *,
|
||||
struct netlink_ext_ack *))
|
||||
{
|
||||
struct netlink_ext_ack extack = {};
|
||||
struct nlmsghdr *nlh;
|
||||
int err;
|
||||
|
||||
|
@ -2328,13 +2392,13 @@ int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
|
|||
if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
|
||||
goto ack;
|
||||
|
||||
err = cb(skb, nlh);
|
||||
err = cb(skb, nlh, &extack);
|
||||
if (err == -EINTR)
|
||||
goto skip;
|
||||
|
||||
ack:
|
||||
if (nlh->nlmsg_flags & NLM_F_ACK || err)
|
||||
netlink_ack(skb, nlh, err);
|
||||
netlink_ack(skb, nlh, err, &extack);
|
||||
|
||||
skip:
|
||||
msglen = NLMSG_ALIGN(nlh->nlmsg_len);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define NETLINK_F_RECV_NO_ENOBUFS 0x8
|
||||
#define NETLINK_F_LISTEN_ALL_NSID 0x10
|
||||
#define NETLINK_F_CAP_ACK 0x20
|
||||
#define NETLINK_F_EXT_ACK 0x40
|
||||
|
||||
#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8)
|
||||
#define NLGRPLONGS(x) (NLGRPSZ(x)/sizeof(unsigned long))
|
||||
|
|
|
@ -497,7 +497,8 @@ static int genl_lock_done(struct netlink_callback *cb)
|
|||
|
||||
static int genl_family_rcv_msg(const struct genl_family *family,
|
||||
struct sk_buff *skb,
|
||||
struct nlmsghdr *nlh)
|
||||
struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct genl_ops *ops;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
|
@ -573,7 +574,7 @@ static int genl_family_rcv_msg(const struct genl_family *family,
|
|||
|
||||
if (attrbuf) {
|
||||
err = nlmsg_parse(nlh, hdrlen, attrbuf, family->maxattr,
|
||||
ops->policy);
|
||||
ops->policy, extack);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
|
@ -584,6 +585,7 @@ static int genl_family_rcv_msg(const struct genl_family *family,
|
|||
info.genlhdr = nlmsg_data(nlh);
|
||||
info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
|
||||
info.attrs = attrbuf;
|
||||
info.extack = extack;
|
||||
genl_info_net_set(&info, net);
|
||||
memset(&info.user_ptr, 0, sizeof(info.user_ptr));
|
||||
|
||||
|
@ -605,7 +607,8 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct genl_family *family;
|
||||
int err;
|
||||
|
@ -617,7 +620,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (!family->parallel_ops)
|
||||
genl_lock();
|
||||
|
||||
err = genl_family_rcv_msg(family, skb, nlh);
|
||||
err = genl_family_rcv_msg(family, skb, nlh, extack);
|
||||
|
||||
if (!family->parallel_ops)
|
||||
genl_unlock();
|
||||
|
|
|
@ -119,7 +119,8 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
|
|||
u32 idx;
|
||||
|
||||
rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
|
||||
attrbuf, nfc_genl_family.maxattr, nfc_genl_policy);
|
||||
attrbuf, nfc_genl_family.maxattr, nfc_genl_policy,
|
||||
NULL);
|
||||
if (rc < 0)
|
||||
return ERR_PTR(rc);
|
||||
|
||||
|
@ -1161,7 +1162,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
nla_for_each_nested(attr, info->attrs[NFC_ATTR_LLC_SDP], rem) {
|
||||
rc = nla_parse_nested(sdp_attrs, NFC_SDP_ATTR_MAX, attr,
|
||||
nfc_sdp_genl_policy);
|
||||
nfc_sdp_genl_policy, info->extack);
|
||||
|
||||
if (rc != 0) {
|
||||
rc = -EINVAL;
|
||||
|
|
|
@ -1353,7 +1353,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
int err;
|
||||
|
||||
err = genlmsg_parse(cb->nlh, &dp_flow_genl_family, a,
|
||||
OVS_FLOW_ATTR_MAX, flow_policy);
|
||||
OVS_FLOW_ATTR_MAX, flow_policy, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
|
||||
|
|
|
@ -2427,8 +2427,8 @@ static int validate_userspace(const struct nlattr *attr)
|
|||
struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1];
|
||||
int error;
|
||||
|
||||
error = nla_parse_nested(a, OVS_USERSPACE_ATTR_MAX,
|
||||
attr, userspace_policy);
|
||||
error = nla_parse_nested(a, OVS_USERSPACE_ATTR_MAX, attr,
|
||||
userspace_policy, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
|
@ -70,7 +70,8 @@ static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
|
|||
if (nla_len(attr) < sizeof(struct nlattr))
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(exts, OVS_VXLAN_EXT_MAX, attr, exts_policy);
|
||||
err = nla_parse_nested(exts, OVS_VXLAN_EXT_MAX, attr, exts_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -78,7 +78,8 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
|
||||
ASSERT_RTNL();
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_phonet_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_phonet_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -243,7 +244,8 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
|
||||
ASSERT_RTNL();
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_phonet_policy);
|
||||
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_phonet_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -957,7 +957,7 @@ static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
|
||||
ASSERT_RTNL();
|
||||
|
||||
rc = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, qrtr_policy);
|
||||
rc = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, qrtr_policy, NULL);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
|
|
@ -557,7 +557,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
|
|||
int err;
|
||||
|
||||
if (name == NULL) {
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
err = -EINVAL;
|
||||
|
@ -654,7 +654,7 @@ int tcf_action_init(struct net *net, struct nlattr *nla, struct nlattr *est,
|
|||
int err;
|
||||
int i;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -786,7 +786,7 @@ static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
|
|||
int index;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
|
||||
|
@ -835,7 +835,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
|
|||
|
||||
b = skb_tail_pointer(skb);
|
||||
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
|
||||
|
@ -921,7 +921,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
|
|||
struct tc_action *act;
|
||||
LIST_HEAD(actions);
|
||||
|
||||
ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
|
||||
ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1004,7 +1004,8 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n)
|
|||
!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
|
||||
ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1051,19 +1052,20 @@ static struct nlattr *find_dump_kind(const struct nlmsghdr *n)
|
|||
struct nlattr *nla[TCAA_MAX + 1];
|
||||
struct nlattr *kind;
|
||||
|
||||
if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, NULL) < 0)
|
||||
if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX,
|
||||
NULL, NULL) < 0)
|
||||
return NULL;
|
||||
tb1 = nla[TCA_ACT_TAB];
|
||||
if (tb1 == NULL)
|
||||
return NULL;
|
||||
|
||||
if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1),
|
||||
NLMSG_ALIGN(nla_len(tb1)), NULL) < 0)
|
||||
NLMSG_ALIGN(nla_len(tb1)), NULL, NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
if (tb[1] == NULL)
|
||||
return NULL;
|
||||
if (nla_parse_nested(tb2, TCA_ACT_MAX, tb[1], NULL) < 0)
|
||||
if (nla_parse_nested(tb2, TCA_ACT_MAX, tb[1], NULL, NULL) < 0)
|
||||
return NULL;
|
||||
kind = tb2[TCA_ACT_KIND];
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
|
|||
if (!nla)
|
||||
return -EINVAL;
|
||||
|
||||
ret = nla_parse_nested(tb, TCA_ACT_BPF_MAX, nla, act_bpf_policy);
|
||||
ret = nla_parse_nested(tb, TCA_ACT_BPF_MAX, nla, act_bpf_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -109,7 +109,8 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
|
|||
if (!nla)
|
||||
return -EINVAL;
|
||||
|
||||
ret = nla_parse_nested(tb, TCA_CONNMARK_MAX, nla, connmark_policy);
|
||||
ret = nla_parse_nested(tb, TCA_CONNMARK_MAX, nla, connmark_policy,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_CSUM_MAX, nla, csum_policy);
|
||||
err = nla_parse_nested(tb, TCA_CSUM_MAX, nla, csum_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_GACT_MAX, nla, gact_policy);
|
||||
err = nla_parse_nested(tb, TCA_GACT_MAX, nla, gact_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -443,7 +443,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
|
|||
int ret = 0;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_IFE_MAX, nla, ife_policy);
|
||||
err = nla_parse_nested(tb, TCA_IFE_MAX, nla, ife_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -514,7 +514,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
|
|||
|
||||
if (tb[TCA_IFE_METALST]) {
|
||||
err = nla_parse_nested(tb2, IFE_META_MAX, tb[TCA_IFE_METALST],
|
||||
NULL);
|
||||
NULL, NULL);
|
||||
if (err) {
|
||||
metadata_parse_err:
|
||||
if (exists)
|
||||
|
|
|
@ -107,7 +107,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_IPT_MAX, nla, ipt_policy);
|
||||
err = nla_parse_nested(tb, TCA_IPT_MAX, nla, ipt_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
|
|||
|
||||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy);
|
||||
ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (tb[TCA_MIRRED_PARMS] == NULL)
|
||||
|
|
|
@ -50,7 +50,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_NAT_MAX, nla, nat_policy);
|
||||
err = nla_parse_nested(tb, TCA_NAT_MAX, nla, nat_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ static struct tcf_pedit_key_ex *tcf_pedit_keys_ex_parse(struct nlattr *nla,
|
|||
}
|
||||
|
||||
err = nla_parse_nested(tb, TCA_PEDIT_KEY_EX_MAX, ka,
|
||||
pedit_key_ex_policy);
|
||||
pedit_key_ex_policy, NULL);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
|
@ -147,7 +147,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_PEDIT_MAX, nla, pedit_policy);
|
||||
err = nla_parse_nested(tb, TCA_PEDIT_MAX, nla, pedit_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_POLICE_MAX, nla, police_policy);
|
||||
err = nla_parse_nested(tb, TCA_POLICE_MAX, nla, police_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
|
|||
|
||||
if (!nla)
|
||||
return -EINVAL;
|
||||
ret = nla_parse_nested(tb, TCA_SAMPLE_MAX, nla, sample_policy);
|
||||
ret = nla_parse_nested(tb, TCA_SAMPLE_MAX, nla, sample_policy, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!tb[TCA_SAMPLE_PARMS] || !tb[TCA_SAMPLE_RATE] ||
|
||||
|
|
|
@ -94,7 +94,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
|
||||
err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
|
|||
if (nla == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_SKBEDIT_MAX, nla, skbedit_policy);
|
||||
err = nla_parse_nested(tb, TCA_SKBEDIT_MAX, nla, skbedit_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
|
|||
if (!nla)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_SKBMOD_MAX, nla, skbmod_policy);
|
||||
err = nla_parse_nested(tb, TCA_SKBMOD_MAX, nla, skbmod_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -89,7 +89,8 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
|
|||
if (!nla)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_TUNNEL_KEY_MAX, nla, tunnel_key_policy);
|
||||
err = nla_parse_nested(tb, TCA_TUNNEL_KEY_MAX, nla, tunnel_key_policy,
|
||||
NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
|
|||
if (!nla)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_VLAN_MAX, nla, vlan_policy);
|
||||
err = nla_parse_nested(tb, TCA_VLAN_MAX, nla, vlan_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
|
|||
replay:
|
||||
tp_created = 0;
|
||||
|
||||
err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL);
|
||||
err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
|
|||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS],
|
||||
basic_policy);
|
||||
basic_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -478,7 +478,8 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
|
|||
if (tca[TCA_OPTIONS] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
ret = nla_parse_nested(tb, TCA_BPF_MAX, tca[TCA_OPTIONS], bpf_policy);
|
||||
ret = nla_parse_nested(tb, TCA_BPF_MAX, tca[TCA_OPTIONS], bpf_policy,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
|
|||
new->handle = handle;
|
||||
new->tp = tp;
|
||||
err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
|
||||
cgroup_policy);
|
||||
cgroup_policy, NULL);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
|
|||
if (opt == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_FLOW_MAX, opt, flow_policy);
|
||||
err = nla_parse_nested(tb, TCA_FLOW_MAX, opt, flow_policy, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче