}
static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
- struct neigh_table **tbl, void **dst,
+ struct nlattr **tb,
struct netlink_ext_ack *extack)
{
- struct nlattr *tb[NDA_MAX + 1];
struct ndmsg *ndm;
int err, i;
if (err < 0)
return ERR_PTR(err);
- *tbl = neigh_find_table(ndm->ndm_family);
- if (!*tbl) {
- NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
- return ERR_PTR(-EAFNOSUPPORT);
- }
-
for (i = 0; i <= NDA_MAX; ++i) {
switch (i) {
case NDA_DST:
NL_SET_ERR_ATTR_MISS(extack, NULL, NDA_DST);
return ERR_PTR(-EINVAL);
}
-
- if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
- NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
- return ERR_PTR(-EINVAL);
- }
- *dst = nla_data(tb[i]);
break;
default:
if (!tb[i])
{
struct net *net = sock_net(in_skb->sk);
u32 pid = NETLINK_CB(in_skb).portid;
+ struct nlattr *tb[NDA_MAX + 1];
struct net_device *dev = NULL;
- struct neigh_table *tbl = NULL;
u32 seq = nlh->nlmsg_seq;
+ struct neigh_table *tbl;
struct neighbour *neigh;
struct sk_buff *skb;
struct ndmsg *ndm;
- void *dst = NULL;
+ void *dst;
int err;
- ndm = neigh_valid_get_req(nlh, &tbl, &dst, extack);
+ ndm = neigh_valid_get_req(nlh, tb, extack);
if (IS_ERR(ndm))
return PTR_ERR(ndm);
if (!skb)
return -ENOBUFS;
+ tbl = neigh_find_table(ndm->ndm_family);
+ if (!tbl) {
+ NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
+ err = -EAFNOSUPPORT;
+ goto err_free_skb;
+ }
+
+ if (nla_len(tb[NDA_DST]) != (int)tbl->key_len) {
+ NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
+ err = -EINVAL;
+ goto err_free_skb;
+ }
+
+ dst = nla_data(tb[NDA_DST]);
+
if (ndm->ndm_ifindex) {
dev = __dev_get_by_index(net, ndm->ndm_ifindex);
if (!dev) {