mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for your net tree: 1) Remove a direct dependency with IPv6 introduced by the sip_external_media feature, from Alin Nastac. 2) Fix bogus ENOENT when removing interval elements from set. 3) Set transport_header from br_netfilter to mimic the stack behaviour, this partially fixes a checksum validation bug from the SCTP connection tracking, from Xin Long. 4) Fix undefined reference to symbol in xt_TEE, due to missing Kconfig dependencies, from Arnd Bergmann. 5) Check for NULL in skb_header_pointer() calls in ip6t_shr, from Kangjie Lu. 6) Fix bogus EBUSY when removing an existing conntrack helper from a transaction. 7) Fix module autoload of the redirect extension. 8) Remove duplicated transition in flowtable diagram in the existing documentation. 9) Missing .release_ops call from error path in newrule() which results module refcount leak, from Taehee Yoo. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
e0831ef716
@ -44,10 +44,10 @@ including the Netfilter hooks and the flowtable fastpath bypass.
|
||||
/ \ / \ |Routing | / \
|
||||
--> ingress ---> prerouting ---> |decision| | postrouting |--> neigh_xmit
|
||||
\_________/ \__________/ ---------- \____________/ ^
|
||||
| ^ | | ^ |
|
||||
flowtable | | ____\/___ | |
|
||||
| | | / \ | |
|
||||
__\/___ | --------->| forward |------------ |
|
||||
| ^ | ^ |
|
||||
flowtable | ____\/___ | |
|
||||
| | / \ | |
|
||||
__\/___ | | forward |------------ |
|
||||
|-----| | \_________/ |
|
||||
|-----| | 'flow offload' rule |
|
||||
|-----| | adds entry to |
|
||||
|
@ -502,6 +502,7 @@ static unsigned int br_nf_pre_routing(void *priv,
|
||||
nf_bridge->ipv4_daddr = ip_hdr(skb)->daddr;
|
||||
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
skb->transport_header = skb->network_header + ip_hdr(skb)->ihl * 4;
|
||||
|
||||
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->net, state->sk, skb,
|
||||
skb->dev, NULL,
|
||||
|
@ -235,6 +235,8 @@ unsigned int br_nf_pre_routing_ipv6(void *priv,
|
||||
nf_bridge->ipv6_daddr = ipv6_hdr(skb)->daddr;
|
||||
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
|
||||
|
||||
NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, state->net, state->sk, skb,
|
||||
skb->dev, NULL,
|
||||
br_nf_pre_routing_finish_ipv6);
|
||||
|
@ -210,6 +210,8 @@ static bool srh1_mt6(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
psidoff = srhoff + sizeof(struct ipv6_sr_hdr) +
|
||||
((srh->segments_left + 1) * sizeof(struct in6_addr));
|
||||
psid = skb_header_pointer(skb, psidoff, sizeof(_psid), &_psid);
|
||||
if (!psid)
|
||||
return false;
|
||||
if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_PSID,
|
||||
ipv6_masked_addr_cmp(psid, &srhinfo->psid_msk,
|
||||
&srhinfo->psid_addr)))
|
||||
@ -223,6 +225,8 @@ static bool srh1_mt6(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
nsidoff = srhoff + sizeof(struct ipv6_sr_hdr) +
|
||||
((srh->segments_left - 1) * sizeof(struct in6_addr));
|
||||
nsid = skb_header_pointer(skb, nsidoff, sizeof(_nsid), &_nsid);
|
||||
if (!nsid)
|
||||
return false;
|
||||
if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_NSID,
|
||||
ipv6_masked_addr_cmp(nsid, &srhinfo->nsid_msk,
|
||||
&srhinfo->nsid_addr)))
|
||||
@ -233,6 +237,8 @@ static bool srh1_mt6(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
if (srhinfo->mt_flags & IP6T_SRH_LSID) {
|
||||
lsidoff = srhoff + sizeof(struct ipv6_sr_hdr);
|
||||
lsid = skb_header_pointer(skb, lsidoff, sizeof(_lsid), &_lsid);
|
||||
if (!lsid)
|
||||
return false;
|
||||
if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_LSID,
|
||||
ipv6_masked_addr_cmp(lsid, &srhinfo->lsid_msk,
|
||||
&srhinfo->lsid_addr)))
|
||||
|
@ -1007,6 +1007,7 @@ config NETFILTER_XT_TARGET_TEE
|
||||
depends on NETFILTER_ADVANCED
|
||||
depends on IPV6 || IPV6=n
|
||||
depends on !NF_CONNTRACK || NF_CONNTRACK
|
||||
depends on IP6_NF_IPTABLES || !IP6_NF_IPTABLES
|
||||
select NF_DUP_IPV4
|
||||
select NF_DUP_IPV6 if IP6_NF_IPTABLES
|
||||
---help---
|
||||
|
@ -20,9 +20,9 @@
|
||||
#include <linux/udp.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv6.h>
|
||||
|
||||
#include <net/route.h>
|
||||
#include <net/ip6_route.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netfilter/nf_conntrack_core.h>
|
||||
#include <net/netfilter/nf_conntrack_expect.h>
|
||||
@ -871,38 +871,33 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
|
||||
} else if (sip_external_media) {
|
||||
struct net_device *dev = skb_dst(skb)->dev;
|
||||
struct net *net = dev_net(dev);
|
||||
struct rtable *rt;
|
||||
struct flowi4 fl4 = {};
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
struct flowi6 fl6 = {};
|
||||
#endif
|
||||
struct flowi fl;
|
||||
struct dst_entry *dst = NULL;
|
||||
|
||||
memset(&fl, 0, sizeof(fl));
|
||||
|
||||
switch (nf_ct_l3num(ct)) {
|
||||
case NFPROTO_IPV4:
|
||||
fl4.daddr = daddr->ip;
|
||||
rt = ip_route_output_key(net, &fl4);
|
||||
if (!IS_ERR(rt))
|
||||
dst = &rt->dst;
|
||||
fl.u.ip4.daddr = daddr->ip;
|
||||
nf_ip_route(net, &dst, &fl, false);
|
||||
break;
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case NFPROTO_IPV6:
|
||||
fl6.daddr = daddr->in6;
|
||||
dst = ip6_route_output(net, NULL, &fl6);
|
||||
if (dst->error) {
|
||||
dst_release(dst);
|
||||
dst = NULL;
|
||||
}
|
||||
fl.u.ip6.daddr = daddr->in6;
|
||||
nf_ip6_route(net, &dst, &fl, false);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Don't predict any conntracks when media endpoint is reachable
|
||||
* through the same interface as the signalling peer.
|
||||
*/
|
||||
if (dst && dst->dev == dev)
|
||||
return NF_ACCEPT;
|
||||
if (dst) {
|
||||
bool external_media = (dst->dev == dev);
|
||||
|
||||
dst_release(dst);
|
||||
if (external_media)
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to check whether the registration exists before attempting
|
||||
|
@ -2806,8 +2806,11 @@ err2:
|
||||
nf_tables_rule_release(&ctx, rule);
|
||||
err1:
|
||||
for (i = 0; i < n; i++) {
|
||||
if (info[i].ops != NULL)
|
||||
if (info[i].ops) {
|
||||
module_put(info[i].ops->type->owner);
|
||||
if (info[i].ops->type->release_ops)
|
||||
info[i].ops->type->release_ops(info[i].ops);
|
||||
}
|
||||
}
|
||||
kvfree(info);
|
||||
return err;
|
||||
|
@ -65,21 +65,34 @@ nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void nft_objref_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr)
|
||||
static void nft_objref_deactivate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr,
|
||||
enum nft_trans_phase phase)
|
||||
{
|
||||
struct nft_object *obj = nft_objref_priv(expr);
|
||||
|
||||
if (phase == NFT_TRANS_COMMIT)
|
||||
return;
|
||||
|
||||
obj->use--;
|
||||
}
|
||||
|
||||
static void nft_objref_activate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr)
|
||||
{
|
||||
struct nft_object *obj = nft_objref_priv(expr);
|
||||
|
||||
obj->use++;
|
||||
}
|
||||
|
||||
static struct nft_expr_type nft_objref_type;
|
||||
static const struct nft_expr_ops nft_objref_ops = {
|
||||
.type = &nft_objref_type,
|
||||
.size = NFT_EXPR_SIZE(sizeof(struct nft_object *)),
|
||||
.eval = nft_objref_eval,
|
||||
.init = nft_objref_init,
|
||||
.destroy = nft_objref_destroy,
|
||||
.activate = nft_objref_activate,
|
||||
.deactivate = nft_objref_deactivate,
|
||||
.dump = nft_objref_dump,
|
||||
};
|
||||
|
||||
|
@ -233,5 +233,5 @@ module_exit(nft_redir_module_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
|
||||
MODULE_ALIAS_NFT_AF_EXPR(AF_INET4, "redir");
|
||||
MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "redir");
|
||||
MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir");
|
||||
|
@ -308,10 +308,6 @@ static void *nft_rbtree_deactivate(const struct net *net,
|
||||
else if (d > 0)
|
||||
parent = parent->rb_right;
|
||||
else {
|
||||
if (!nft_set_elem_active(&rbe->ext, genmask)) {
|
||||
parent = parent->rb_left;
|
||||
continue;
|
||||
}
|
||||
if (nft_rbtree_interval_end(rbe) &&
|
||||
!nft_rbtree_interval_end(this)) {
|
||||
parent = parent->rb_left;
|
||||
@ -320,6 +316,9 @@ static void *nft_rbtree_deactivate(const struct net *net,
|
||||
nft_rbtree_interval_end(this)) {
|
||||
parent = parent->rb_right;
|
||||
continue;
|
||||
} else if (!nft_set_elem_active(&rbe->ext, genmask)) {
|
||||
parent = parent->rb_left;
|
||||
continue;
|
||||
}
|
||||
nft_rbtree_flush(net, set, rbe);
|
||||
return rbe;
|
||||
|
Loading…
Reference in New Issue
Block a user