Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b11dabfd authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-more-extack'



David Ahern says:

====================
net: another round of extack handling for routing

This set focuses on passing extack through lwtunnel and MPLS with
additional catches for IPv4 route add and minor cleanups in MPLS
encountered passing the extack arg around.

v2
- mindful of bloat adding duplicate messages
  + refactored prefix and prefix length checks in ipv4's fib_table_insert
    and fib_table_del
  + refactored label check in mpls

- split mpls cleanups into 2 patches
  + move nla_get_via up in af_mpls to avoid forward declaration
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f1bd4dae e1af005b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -102,6 +102,16 @@ struct netlink_ext_ack {
		(extack)->bad_attr = (attr);		\
} while (0)

#define NL_SET_ERR_MSG_ATTR(extack, attr, msg) do {	\
	static const char __msg[] = (msg);		\
	struct netlink_ext_ack *__extack = (extack);	\
							\
	if (__extack) {					\
		__extack->_msg = __msg;			\
		__extack->bad_attr = (attr);		\
	}						\
} 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);
+2 −1
Original line number Diff line number Diff line
@@ -266,7 +266,8 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
		     struct fib_result *res, int fib_flags);
int fib_table_insert(struct net *, struct fib_table *, struct fib_config *,
		     struct netlink_ext_ack *extack);
int fib_table_delete(struct net *, struct fib_table *, struct fib_config *);
int fib_table_delete(struct net *, struct fib_table *, struct fib_config *,
		     struct netlink_ext_ack *extack);
int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
		   struct netlink_callback *cb);
int fib_table_flush(struct net *net, struct fib_table *table);
+15 −7
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ struct lwtunnel_state {
struct lwtunnel_encap_ops {
	int (*build_state)(struct nlattr *encap,
			   unsigned int family, const void *cfg,
			   struct lwtunnel_state **ts);
			   struct lwtunnel_state **ts,
			   struct netlink_ext_ack *extack);
	void (*destroy_state)(struct lwtunnel_state *lws);
	int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
	int (*input)(struct sk_buff *skb);
@@ -107,12 +108,15 @@ int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
			   unsigned int num);
int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
			   unsigned int num);
int lwtunnel_valid_encap_type(u16 encap_type);
int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len);
int lwtunnel_valid_encap_type(u16 encap_type,
			      struct netlink_ext_ack *extack);
int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
				   struct netlink_ext_ack *extack);
int lwtunnel_build_state(u16 encap_type,
			 struct nlattr *encap,
			 unsigned int family, const void *cfg,
			 struct lwtunnel_state **lws);
			 struct lwtunnel_state **lws,
			 struct netlink_ext_ack *extack);
int lwtunnel_fill_encap(struct sk_buff *skb,
			struct lwtunnel_state *lwtstate);
int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
@@ -172,11 +176,14 @@ static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
	return -EOPNOTSUPP;
}

static inline int lwtunnel_valid_encap_type(u16 encap_type)
static inline int lwtunnel_valid_encap_type(u16 encap_type,
					    struct netlink_ext_ack *extack)
{
	NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel");
	return -EOPNOTSUPP;
}
static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len)
static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
						 struct netlink_ext_ack *extack)
{
	/* return 0 since we are not walking attr looking for
	 * RTA_ENCAP_TYPE attribute on nexthops.
@@ -187,7 +194,8 @@ static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len)
static inline int lwtunnel_build_state(u16 encap_type,
				       struct nlattr *encap,
				       unsigned int family, const void *cfg,
				       struct lwtunnel_state **lws)
				       struct lwtunnel_state **lws,
				       struct netlink_ext_ack *extack)
{
	return -EOPNOTSUPP;
}
+3 −2
Original line number Diff line number Diff line
@@ -240,7 +240,8 @@ static const struct nla_policy bpf_nl_policy[LWT_BPF_MAX + 1] = {

static int bpf_build_state(struct nlattr *nla,
			   unsigned int family, const void *cfg,
			   struct lwtunnel_state **ts)
			   struct lwtunnel_state **ts,
			   struct netlink_ext_ack *extack)
{
	struct nlattr *tb[LWT_BPF_MAX + 1];
	struct lwtunnel_state *newts;
@@ -250,7 +251,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, NULL);
	ret = nla_parse_nested(tb, LWT_BPF_MAX, nla, bpf_nl_policy, extack);
	if (ret < 0)
		return ret;

+30 −8
Original line number Diff line number Diff line
@@ -103,37 +103,53 @@ EXPORT_SYMBOL(lwtunnel_encap_del_ops);

int lwtunnel_build_state(u16 encap_type,
			 struct nlattr *encap, unsigned int family,
			 const void *cfg, struct lwtunnel_state **lws)
			 const void *cfg, struct lwtunnel_state **lws,
			 struct netlink_ext_ack *extack)
{
	const struct lwtunnel_encap_ops *ops;
	bool found = false;
	int ret = -EINVAL;

	if (encap_type == LWTUNNEL_ENCAP_NONE ||
	    encap_type > LWTUNNEL_ENCAP_MAX)
	    encap_type > LWTUNNEL_ENCAP_MAX) {
		NL_SET_ERR_MSG_ATTR(extack, encap,
				    "Unknown LWT encapsulation type");
		return ret;
	}

	ret = -EOPNOTSUPP;
	rcu_read_lock();
	ops = rcu_dereference(lwtun_encaps[encap_type]);
	if (likely(ops && ops->build_state && try_module_get(ops->owner))) {
		ret = ops->build_state(encap, family, cfg, lws);
		found = true;
		ret = ops->build_state(encap, family, cfg, lws, extack);
		if (ret)
			module_put(ops->owner);
	}
	rcu_read_unlock();

	/* don't rely on -EOPNOTSUPP to detect match as build_state
	 * handlers could return it
	 */
	if (!found) {
		NL_SET_ERR_MSG_ATTR(extack, encap,
				    "LWT encapsulation type not supported");
	}

	return ret;
}
EXPORT_SYMBOL(lwtunnel_build_state);

int lwtunnel_valid_encap_type(u16 encap_type)
int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack)
{
	const struct lwtunnel_encap_ops *ops;
	int ret = -EINVAL;

	if (encap_type == LWTUNNEL_ENCAP_NONE ||
	    encap_type > LWTUNNEL_ENCAP_MAX)
	    encap_type > LWTUNNEL_ENCAP_MAX) {
		NL_SET_ERR_MSG(extack, "Unknown lwt encapsulation type");
		return ret;
	}

	rcu_read_lock();
	ops = rcu_dereference(lwtun_encaps[encap_type]);
@@ -153,11 +169,16 @@ int lwtunnel_valid_encap_type(u16 encap_type)
		}
	}
#endif
	return ops ? 0 : -EOPNOTSUPP;
	ret = ops ? 0 : -EOPNOTSUPP;
	if (ret < 0)
		NL_SET_ERR_MSG(extack, "lwt encapsulation type not supported");

	return ret;
}
EXPORT_SYMBOL(lwtunnel_valid_encap_type);

int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining)
int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining,
				   struct netlink_ext_ack *extack)
{
	struct rtnexthop *rtnh = (struct rtnexthop *)attr;
	struct nlattr *nla_entype;
@@ -174,7 +195,8 @@ int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining)
			if (nla_entype) {
				encap_type = nla_get_u16(nla_entype);

				if (lwtunnel_valid_encap_type(encap_type) != 0)
				if (lwtunnel_valid_encap_type(encap_type,
							      extack) != 0)
					return -EOPNOTSUPP;
			}
		}
Loading