From 55923f521476a601feeea5ab3a12273ac2141441 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Sat, 26 Jun 2021 23:06:20 +0200 Subject: Backport "netfilter: use nfnetlink_unicast()" Backport patch "netfilter: use nfnetlink_unicast()" from Pablo Neira Ayuso . Signed-off-by: Jozsef Kadlecsik --- .../linux/netfilter/ipset/ip_set_compat.h.in | 23 ++++++++++ kernel/net/netfilter/ipset/ip_set_core.c | 50 +++++----------------- 2 files changed, 33 insertions(+), 40 deletions(-) (limited to 'kernel') diff --git a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in index af6424d..4d2c446 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in +++ b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in @@ -65,6 +65,8 @@ #@HAVE_NFNL_MSG_PUT@ HAVE_NFNL_MSG_PUT #@HAVE_NFNL_INFO_IN_NFNL_CALLBACK@ HAVE_NFNL_INFO_IN_NFNL_CALLBACK #@HAVE_NFNL_CALLBACK_TYPE@ HAVE_NFNL_CALLBACK_TYPE +#@HAVE_EAGAIN_IN_NFNETLINK_UNICAST@ HAVE_EAGAIN_IN_NFNETLINK_UNICAST +#@HAVE_NLMSG_UNICAST@ HAVE_NLMSG_UNICAST #ifdef HAVE_EXPORT_SYMBOL_GPL_IN_MODULE_H #include @@ -358,6 +360,7 @@ static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype, #define INFO_NLH(i, n) (i)->nlh #define INFO_NET(i, n) (i)->net #define INFO_SK(i, n) (i)->sk +#define CALL_AD(net, ctnl, skb, set, tb, adt, flags, l) call_ad(net, ctnl, skb, set, tb, adt, flags, l) #elif defined(HAVE_PASSING_EXTENDED_ACK_TO_CALLBACKS) #define IPSET_CBFN(fn, net, nl, skb, nlh, cda, e, i) fn(net, nl, skb, nlh, cda, e) #define IPSET_CBFN_AD(fn, net, nl, skb, ad, nlh, cda, e, i) fn(net, nl, skb, ad, nlh, cda, e) @@ -365,6 +368,7 @@ static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype, #define INFO_NLH(i, n) n #define INFO_NET(i, n) n #define INFO_SK(i, n) n +#define CALL_AD(net, ctnl, skb, set, tb, adt, flags, l) call_ad(net, ctnl, skb, set, tb, adt, flags, l) #elif defined(HAVE_NET_IN_NFNL_CALLBACK_FN) #define IPSET_CBFN(fn, net, nl, skb, nlh, cda, e, i) fn(net, nl, skb, nlh, cda) #define IPSET_CBFN_AD(fn, net, nl, skb, ad, nlh, cda, e, i) fn(net, nl, skb, ad, nlh, cda) @@ -372,6 +376,7 @@ static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype, #define INFO_NLH(i, n) n #define INFO_NET(i, n) n #define INFO_SK(i, n) n +#define CALL_AD(net, ctnl, skb, set, tb, adt, flags, l) call_ad(net, ctnl, skb, set, tb, adt, flags, l) #else #define IPSET_CBFN(fn, net, nl, skb, nlh, cda, e, i) fn(nl, skb, nlh, cda) #define IPSET_CBFN_AD(fn, net, nl, skb, ad, nlh, cda, e, i) fn(nl, skb, ad, nlh, cda) @@ -379,6 +384,7 @@ static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype, #define INFO_NLH(i, n) n #define INFO_NET(i, n) n #define INFO_SK(i, n) n +#define CALL_AD(net, ctnl, skb, set, tb, adt, flags, l) call_ad(ctnl, skb, set, tb, adt, flags, l) #endif #ifdef HAVE_NFNL_CALLBACK_TYPE @@ -514,6 +520,23 @@ static inline ssize_t strscpy(char * dest, const char * src, size_t count) #define nla_strscpy nla_strlcpy #endif +#if !defined(HAVE_EAGAIN_IN_NFNETLINK_UNICAST) || !defined(HAVE_NLMSG_UNICAST) +#define NFNETLINK_UNICAST(cntl, skb, net, portid) ipset_nfnetlink_unicast(cntl, skb, portid) +static inline int ipset_nfnetlink_unicast(struct sock *ctnl, struct sk_buff *skb, u32 portid) +{ + int err = netlink_unicast(ctnl, skb, portid, MSG_DONTWAIT); + + if (err > 0) + err = 0; + if (err == -EAGAIN) + err = -ENOBUFS; + + return err; +} +#else +#define NFNETLINK_UNICAST(cntl, skb, net, portid) nfnetlink_unicast(skb, net, portid) +#endif + #ifndef smp_mb__before_atomic #define smp_mb__before_atomic() smp_mb() #define smp_mb__after_atomic() smp_mb() diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c index 4c86089..0fdafb7 100644 --- a/kernel/net/netfilter/ipset/ip_set_core.c +++ b/kernel/net/netfilter/ipset/ip_set_core.c @@ -1741,8 +1741,8 @@ static const struct nla_policy ip_set_adt_policy[IPSET_ATTR_CMD_MAX + 1] = { }; static int -call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set, - struct nlattr *tb[], enum ipset_adt adt, +CALL_AD(struct net *net, struct sock *ctnl, struct sk_buff *skb, + struct ip_set *set, struct nlattr *tb[], enum ipset_adt adt, u32 flags, bool use_lineno) { int ret; @@ -1794,8 +1794,7 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set, *errline = lineno; - netlink_unicast(ctnl, skb2, NETLINK_PORTID(skb), - MSG_DONTWAIT); + NFNETLINK_UNICAST(ctnl, skb2, net, NETLINK_PORTID(skb)); /* Signal netlink not to send its ACK/errmsg. */ return -EINTR; } @@ -1839,7 +1838,7 @@ static int IPSET_CBFN_AD(ip_set_ad, struct net *net, struct sock *ctnl, attr[IPSET_ATTR_DATA], set->type->adt_policy, NULL)) return -IPSET_ERR_PROTOCOL; - ret = call_ad(ctnl, skb, set, tb, adt, flags, + ret = CALL_AD(net, ctnl, skb, set, tb, adt, flags, use_lineno); } else { int nla_rem; @@ -1850,7 +1849,7 @@ static int IPSET_CBFN_AD(ip_set_ad, struct net *net, struct sock *ctnl, NLA_PARSE_NESTED(tb, IPSET_ATTR_ADT_MAX, nla, set->type->adt_policy, NULL)) return -IPSET_ERR_PROTOCOL; - ret = call_ad(ctnl, skb, set, tb, adt, + ret = CALL_AD(net, ctnl, skb, set, tb, adt, flags, use_lineno); if (ret < 0) return ret; @@ -1932,7 +1931,6 @@ IPSET_CBFN(ip_set_header, struct net *net, struct sock *ctnl, const struct ip_set *set; struct sk_buff *skb2; struct nlmsghdr *nlh2; - int ret = 0; if (unlikely(protocol_min_failed(attr) || !attr[IPSET_ATTR_SETNAME])) @@ -1958,12 +1956,7 @@ IPSET_CBFN(ip_set_header, struct net *net, struct sock *ctnl, goto nla_put_failure; nlmsg_end(skb2, nlh2); - ret = netlink_unicast(INFO_SK(info, ctnl), skb2, NETLINK_PORTID(skb), - MSG_DONTWAIT); - if (ret < 0) - return ret; - - return 0; + return NFNETLINK_UNICAST(INFO_SK(info, ctnl), skb2, INFO_NET(info, net), NETLINK_PORTID(skb)); nla_put_failure: nlmsg_cancel(skb2, nlh2); @@ -2022,12 +2015,7 @@ IPSET_CBFN(ip_set_type, struct net *net, struct sock *ctnl, nlmsg_end(skb2, nlh2); pr_debug("Send TYPE, nlmsg_len: %u\n", nlh2->nlmsg_len); - ret = netlink_unicast(INFO_SK(info, ctnl), skb2, NETLINK_PORTID(skb), - MSG_DONTWAIT); - if (ret < 0) - return ret; - - return 0; + return NFNETLINK_UNICAST(INFO_SK(info, ctnl), skb2, INFO_NET(info, net), NETLINK_PORTID(skb)); nla_put_failure: nlmsg_cancel(skb2, nlh2); @@ -2052,7 +2040,6 @@ IPSET_CBFN(ip_set_protocol, struct net *net, struct sock *ctnl, { struct sk_buff *skb2; struct nlmsghdr *nlh2; - int ret = 0; if (unlikely(!attr[IPSET_ATTR_PROTOCOL])) return -IPSET_ERR_PROTOCOL; @@ -2071,12 +2058,7 @@ IPSET_CBFN(ip_set_protocol, struct net *net, struct sock *ctnl, goto nla_put_failure; nlmsg_end(skb2, nlh2); - ret = netlink_unicast(INFO_SK(info, ctnl), skb2, NETLINK_PORTID(skb), - MSG_DONTWAIT); - if (ret < 0) - return ret; - - return 0; + return NFNETLINK_UNICAST(INFO_SK(info, ctnl), skb2, INFO_NET(info, net), NETLINK_PORTID(skb)); nla_put_failure: nlmsg_cancel(skb2, nlh2); @@ -2099,7 +2081,6 @@ IPSET_CBFN(ip_set_byname, struct net *net, struct sock *ctnl, struct nlmsghdr *nlh2; ip_set_id_t id = IPSET_INVALID_ID; const struct ip_set *set; - int ret = 0; if (unlikely(protocol_failed(attr) || !attr[IPSET_ATTR_SETNAME])) @@ -2123,12 +2104,7 @@ IPSET_CBFN(ip_set_byname, struct net *net, struct sock *ctnl, goto nla_put_failure; nlmsg_end(skb2, nlh2); - ret = netlink_unicast(INFO_SK(info, ctnl), skb2, NETLINK_PORTID(skb), - MSG_DONTWAIT); - if (ret < 0) - return ret; - - return 0; + return NFNETLINK_UNICAST(INFO_SK(info, ctnl), skb2, INFO_NET(info, net), NETLINK_PORTID(skb)); nla_put_failure: nlmsg_cancel(skb2, nlh2); @@ -2154,7 +2130,6 @@ IPSET_CBFN(ip_set_byindex, struct net *net, struct sock *ctnl, struct nlmsghdr *nlh2; ip_set_id_t id = IPSET_INVALID_ID; const struct ip_set *set; - int ret = 0; if (unlikely(protocol_failed(attr) || !attr[IPSET_ATTR_INDEX])) @@ -2180,12 +2155,7 @@ IPSET_CBFN(ip_set_byindex, struct net *net, struct sock *ctnl, goto nla_put_failure; nlmsg_end(skb2, nlh2); - ret = netlink_unicast(INFO_SK(info, ctnl), skb2, NETLINK_PORTID(skb), - MSG_DONTWAIT); - if (ret < 0) - return ret; - - return 0; + return NFNETLINK_UNICAST(INFO_SK(info, ctnl), skb2, INFO_NET(info, net), NETLINK_PORTID(skb)); nla_put_failure: nlmsg_cancel(skb2, nlh2); -- cgit v1.2.3