mirror of
https://github.com/a52xq-dev/kernel.git
synced 2026-10-18 21:58:11 +07:00
netfilter: x_tables: move hook state into xt_action_param structure
Place pointer to hook state in xt_action_param structure instead of copying the fields that we need. After this change xt_action_param fits into one cacheline. This patch also adds a set of new wrapper functions to fetch relevant hook state structure fields. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
06fd3a392b
commit
613dbd9572
46 changed files with 196 additions and 169 deletions
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/static_key.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <uapi/linux/netfilter/x_tables.h>
|
||||
|
||||
/* Test a struct->invflags and a boolean for inequality */
|
||||
|
|
@ -17,14 +18,9 @@
|
|||
* @target: the target extension
|
||||
* @matchinfo: per-match data
|
||||
* @targetinfo: per-target data
|
||||
* @net network namespace through which the action was invoked
|
||||
* @in: input netdevice
|
||||
* @out: output netdevice
|
||||
* @state: pointer to hook state this packet came from
|
||||
* @fragoff: packet is a fragment, this is the data offset
|
||||
* @thoff: position of transport header relative to skb->data
|
||||
* @hook: hook number given packet came from
|
||||
* @family: Actual NFPROTO_* through which the function is invoked
|
||||
* (helpful when match->family == NFPROTO_UNSPEC)
|
||||
*
|
||||
* Fields written to by extensions:
|
||||
*
|
||||
|
|
@ -38,15 +34,47 @@ struct xt_action_param {
|
|||
union {
|
||||
const void *matchinfo, *targinfo;
|
||||
};
|
||||
struct net *net;
|
||||
const struct net_device *in, *out;
|
||||
const struct nf_hook_state *state;
|
||||
int fragoff;
|
||||
unsigned int thoff;
|
||||
unsigned int hooknum;
|
||||
u_int8_t family;
|
||||
bool hotdrop;
|
||||
};
|
||||
|
||||
static inline struct net *xt_net(const struct xt_action_param *par)
|
||||
{
|
||||
return par->state->net;
|
||||
}
|
||||
|
||||
static inline struct net_device *xt_in(const struct xt_action_param *par)
|
||||
{
|
||||
return par->state->in;
|
||||
}
|
||||
|
||||
static inline const char *xt_inname(const struct xt_action_param *par)
|
||||
{
|
||||
return par->state->in->name;
|
||||
}
|
||||
|
||||
static inline struct net_device *xt_out(const struct xt_action_param *par)
|
||||
{
|
||||
return par->state->out;
|
||||
}
|
||||
|
||||
static inline const char *xt_outname(const struct xt_action_param *par)
|
||||
{
|
||||
return par->state->out->name;
|
||||
}
|
||||
|
||||
static inline unsigned int xt_hooknum(const struct xt_action_param *par)
|
||||
{
|
||||
return par->state->hook;
|
||||
}
|
||||
|
||||
static inline u_int8_t xt_family(const struct xt_action_param *par)
|
||||
{
|
||||
return par->state->pf;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct xt_mtchk_param - parameters for match extensions'
|
||||
* checkentry functions
|
||||
|
|
|
|||
|
|
@ -30,11 +30,12 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
|
|||
const struct nf_hook_state *state)
|
||||
{
|
||||
pkt->skb = skb;
|
||||
pkt->net = pkt->xt.net = state->net;
|
||||
pkt->in = pkt->xt.in = state->in;
|
||||
pkt->out = pkt->xt.out = state->out;
|
||||
pkt->hook = pkt->xt.hooknum = state->hook;
|
||||
pkt->pf = pkt->xt.family = state->pf;
|
||||
pkt->net = state->net;
|
||||
pkt->in = state->in;
|
||||
pkt->out = state->out;
|
||||
pkt->hook = state->hook;
|
||||
pkt->pf = state->pf;
|
||||
pkt->xt.state = state;
|
||||
}
|
||||
|
||||
static inline void nft_set_pktinfo_proto_unspec(struct nft_pktinfo *pkt,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ ebt_arpreply_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
if (diptr == NULL)
|
||||
return EBT_DROP;
|
||||
|
||||
arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)par->in,
|
||||
arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr,
|
||||
(struct net_device *)xt_in(par),
|
||||
*diptr, shp, info->mac, shp);
|
||||
|
||||
return info->target;
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
{
|
||||
const struct ebt_log_info *info = par->targinfo;
|
||||
struct nf_loginfo li;
|
||||
struct net *net = par->net;
|
||||
struct net *net = xt_net(par);
|
||||
|
||||
li.type = NF_LOG_TYPE_LOG;
|
||||
li.u.log.level = info->loglevel;
|
||||
|
|
@ -190,11 +190,12 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
* nf_log_packet() with NFT_LOG_TYPE_LOG here. --Pablo
|
||||
*/
|
||||
if (info->bitmask & EBT_LOG_NFLOG)
|
||||
nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb,
|
||||
par->in, par->out, &li, "%s", info->prefix);
|
||||
nf_log_packet(net, NFPROTO_BRIDGE, xt_hooknum(par), skb,
|
||||
xt_in(par), xt_out(par), &li, "%s",
|
||||
info->prefix);
|
||||
else
|
||||
ebt_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in,
|
||||
par->out, &li, info->prefix);
|
||||
ebt_log_packet(net, NFPROTO_BRIDGE, xt_hooknum(par), skb,
|
||||
xt_in(par), xt_out(par), &li, info->prefix);
|
||||
return EBT_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ static unsigned int
|
|||
ebt_nflog_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct ebt_nflog_info *info = par->targinfo;
|
||||
struct net *net = xt_net(par);
|
||||
struct nf_loginfo li;
|
||||
struct net *net = par->net;
|
||||
|
||||
li.type = NF_LOG_TYPE_ULOG;
|
||||
li.u.ulog.copy_len = info->len;
|
||||
li.u.ulog.group = info->group;
|
||||
li.u.ulog.qthreshold = info->threshold;
|
||||
|
||||
nf_log_packet(net, PF_BRIDGE, par->hooknum, skb, par->in,
|
||||
par->out, &li, "%s", info->prefix);
|
||||
nf_log_packet(net, PF_BRIDGE, xt_hooknum(par), skb, xt_in(par),
|
||||
xt_out(par), &li, "%s", info->prefix);
|
||||
return EBT_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
if (!skb_make_writable(skb, 0))
|
||||
return EBT_DROP;
|
||||
|
||||
if (par->hooknum != NF_BR_BROUTING)
|
||||
if (xt_hooknum(par) != NF_BR_BROUTING)
|
||||
/* rcu_read_lock()ed by nf_hook_thresh */
|
||||
ether_addr_copy(eth_hdr(skb)->h_dest,
|
||||
br_port_get_rcu(par->in)->br->dev->dev_addr);
|
||||
br_port_get_rcu(xt_in(par))->br->dev->dev_addr);
|
||||
else
|
||||
ether_addr_copy(eth_hdr(skb)->h_dest, par->in->dev_addr);
|
||||
ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr);
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
return info->target;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,12 +194,8 @@ unsigned int ebt_do_table(struct sk_buff *skb,
|
|||
const struct ebt_table_info *private;
|
||||
struct xt_action_param acpar;
|
||||
|
||||
acpar.family = NFPROTO_BRIDGE;
|
||||
acpar.net = state->net;
|
||||
acpar.in = state->in;
|
||||
acpar.out = state->out;
|
||||
acpar.state = state;
|
||||
acpar.hotdrop = false;
|
||||
acpar.hooknum = hook;
|
||||
|
||||
read_lock_bh(&table->lock);
|
||||
private = table->private;
|
||||
|
|
|
|||
|
|
@ -217,11 +217,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
|||
*/
|
||||
e = get_entry(table_base, private->hook_entry[hook]);
|
||||
|
||||
acpar.net = state->net;
|
||||
acpar.in = state->in;
|
||||
acpar.out = state->out;
|
||||
acpar.hooknum = hook;
|
||||
acpar.family = NFPROTO_ARP;
|
||||
acpar.state = state;
|
||||
acpar.hotdrop = false;
|
||||
|
||||
arp = arp_hdr(skb);
|
||||
|
|
|
|||
|
|
@ -261,11 +261,7 @@ ipt_do_table(struct sk_buff *skb,
|
|||
acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
|
||||
acpar.thoff = ip_hdrlen(skb);
|
||||
acpar.hotdrop = false;
|
||||
acpar.net = state->net;
|
||||
acpar.in = state->in;
|
||||
acpar.out = state->out;
|
||||
acpar.family = NFPROTO_IPV4;
|
||||
acpar.hooknum = hook;
|
||||
acpar.state = state;
|
||||
|
||||
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||
local_bh_disable();
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
range.min_proto = mr->range[0].min;
|
||||
range.max_proto = mr->range[0].max;
|
||||
|
||||
return nf_nat_masquerade_ipv4(skb, par->hooknum, &range, par->out);
|
||||
return nf_nat_masquerade_ipv4(skb, xt_hooknum(par), &range,
|
||||
xt_out(par));
|
||||
}
|
||||
|
||||
static struct xt_target masquerade_tg_reg __read_mostly = {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ static unsigned int
|
|||
reject_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct ipt_reject_info *reject = par->targinfo;
|
||||
int hook = par->hooknum;
|
||||
int hook = xt_hooknum(par);
|
||||
|
||||
switch (reject->with) {
|
||||
case IPT_ICMP_NET_UNREACHABLE:
|
||||
|
|
@ -59,7 +59,7 @@ reject_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
nf_send_unreach(skb, ICMP_PKT_FILTERED, hook);
|
||||
break;
|
||||
case IPT_TCP_RESET:
|
||||
nf_send_reset(par->net, skb, hook);
|
||||
nf_send_reset(xt_net(par), skb, hook);
|
||||
case IPT_ICMP_ECHOREPLY:
|
||||
/* Doesn't happen. */
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -263,12 +263,12 @@ static unsigned int
|
|||
synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_synproxy_info *info = par->targinfo;
|
||||
struct net *net = par->net;
|
||||
struct net *net = xt_net(par);
|
||||
struct synproxy_net *snet = synproxy_pernet(net);
|
||||
struct synproxy_options opts = {};
|
||||
struct tcphdr *th, _th;
|
||||
|
||||
if (nf_ip_checksum(skb, par->hooknum, par->thoff, IPPROTO_TCP))
|
||||
if (nf_ip_checksum(skb, xt_hooknum(par), par->thoff, IPPROTO_TCP))
|
||||
return NF_DROP;
|
||||
|
||||
th = skb_header_pointer(skb, par->thoff, sizeof(_th), &_th);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
flow.flowi4_tos = RT_TOS(iph->tos);
|
||||
flow.flowi4_scope = RT_SCOPE_UNIVERSE;
|
||||
|
||||
return rpfilter_lookup_reverse(par->net, &flow, par->in, info->flags) ^ invert;
|
||||
return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert;
|
||||
}
|
||||
|
||||
static int rpfilter_check(const struct xt_mtchk_param *par)
|
||||
|
|
|
|||
|
|
@ -291,11 +291,7 @@ ip6t_do_table(struct sk_buff *skb,
|
|||
* rule is also a fragment-specific rule, non-fragments won't
|
||||
* match it. */
|
||||
acpar.hotdrop = false;
|
||||
acpar.net = state->net;
|
||||
acpar.in = state->in;
|
||||
acpar.out = state->out;
|
||||
acpar.family = NFPROTO_IPV6;
|
||||
acpar.hooknum = hook;
|
||||
acpar.state = state;
|
||||
|
||||
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
static unsigned int
|
||||
masquerade_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
return nf_nat_masquerade_ipv6(skb, par->targinfo, par->out);
|
||||
return nf_nat_masquerade_ipv6(skb, par->targinfo, xt_out(par));
|
||||
}
|
||||
|
||||
static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
|
||||
|
|
|
|||
|
|
@ -39,35 +39,40 @@ static unsigned int
|
|||
reject_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct ip6t_reject_info *reject = par->targinfo;
|
||||
struct net *net = par->net;
|
||||
struct net *net = xt_net(par);
|
||||
|
||||
switch (reject->with) {
|
||||
case IP6T_ICMP6_NO_ROUTE:
|
||||
nf_send_unreach6(net, skb, ICMPV6_NOROUTE, par->hooknum);
|
||||
nf_send_unreach6(net, skb, ICMPV6_NOROUTE, xt_hooknum(par));
|
||||
break;
|
||||
case IP6T_ICMP6_ADM_PROHIBITED:
|
||||
nf_send_unreach6(net, skb, ICMPV6_ADM_PROHIBITED, par->hooknum);
|
||||
nf_send_unreach6(net, skb, ICMPV6_ADM_PROHIBITED,
|
||||
xt_hooknum(par));
|
||||
break;
|
||||
case IP6T_ICMP6_NOT_NEIGHBOUR:
|
||||
nf_send_unreach6(net, skb, ICMPV6_NOT_NEIGHBOUR, par->hooknum);
|
||||
nf_send_unreach6(net, skb, ICMPV6_NOT_NEIGHBOUR,
|
||||
xt_hooknum(par));
|
||||
break;
|
||||
case IP6T_ICMP6_ADDR_UNREACH:
|
||||
nf_send_unreach6(net, skb, ICMPV6_ADDR_UNREACH, par->hooknum);
|
||||
nf_send_unreach6(net, skb, ICMPV6_ADDR_UNREACH,
|
||||
xt_hooknum(par));
|
||||
break;
|
||||
case IP6T_ICMP6_PORT_UNREACH:
|
||||
nf_send_unreach6(net, skb, ICMPV6_PORT_UNREACH, par->hooknum);
|
||||
nf_send_unreach6(net, skb, ICMPV6_PORT_UNREACH,
|
||||
xt_hooknum(par));
|
||||
break;
|
||||
case IP6T_ICMP6_ECHOREPLY:
|
||||
/* Do nothing */
|
||||
break;
|
||||
case IP6T_TCP_RESET:
|
||||
nf_send_reset6(net, skb, par->hooknum);
|
||||
nf_send_reset6(net, skb, xt_hooknum(par));
|
||||
break;
|
||||
case IP6T_ICMP6_POLICY_FAIL:
|
||||
nf_send_unreach6(net, skb, ICMPV6_POLICY_FAIL, par->hooknum);
|
||||
nf_send_unreach6(net, skb, ICMPV6_POLICY_FAIL, xt_hooknum(par));
|
||||
break;
|
||||
case IP6T_ICMP6_REJECT_ROUTE:
|
||||
nf_send_unreach6(net, skb, ICMPV6_REJECT_ROUTE, par->hooknum);
|
||||
nf_send_unreach6(net, skb, ICMPV6_REJECT_ROUTE,
|
||||
xt_hooknum(par));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -277,12 +277,12 @@ static unsigned int
|
|||
synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_synproxy_info *info = par->targinfo;
|
||||
struct net *net = par->net;
|
||||
struct net *net = xt_net(par);
|
||||
struct synproxy_net *snet = synproxy_pernet(net);
|
||||
struct synproxy_options opts = {};
|
||||
struct tcphdr *th, _th;
|
||||
|
||||
if (nf_ip6_checksum(skb, par->hooknum, par->thoff, IPPROTO_TCP))
|
||||
if (nf_ip6_checksum(skb, xt_hooknum(par), par->thoff, IPPROTO_TCP))
|
||||
return NF_DROP;
|
||||
|
||||
th = skb_header_pointer(skb, par->thoff, sizeof(_th), &_th);
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
if (unlikely(saddrtype == IPV6_ADDR_ANY))
|
||||
return true ^ invert; /* not routable: forward path will drop it */
|
||||
|
||||
return rpfilter_lookup_reverse6(par->net, skb, par->in, info->flags) ^ invert;
|
||||
return rpfilter_lookup_reverse6(xt_net(par), skb, xt_in(par),
|
||||
info->flags) ^ invert;
|
||||
}
|
||||
|
||||
static int rpfilter_check(const struct xt_mtchk_param *par)
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ int
|
|||
ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
|
||||
const struct xt_action_param *par, struct ip_set_adt_opt *opt)
|
||||
{
|
||||
struct ip_set *set = ip_set_rcu_get(par->net, index);
|
||||
struct ip_set *set = ip_set_rcu_get(xt_net(par), index);
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(!set);
|
||||
|
|
@ -579,7 +579,7 @@ int
|
|||
ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
|
||||
const struct xt_action_param *par, struct ip_set_adt_opt *opt)
|
||||
{
|
||||
struct ip_set *set = ip_set_rcu_get(par->net, index);
|
||||
struct ip_set *set = ip_set_rcu_get(xt_net(par), index);
|
||||
int ret;
|
||||
|
||||
BUG_ON(!set);
|
||||
|
|
@ -601,7 +601,7 @@ int
|
|||
ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
|
||||
const struct xt_action_param *par, struct ip_set_adt_opt *opt)
|
||||
{
|
||||
struct ip_set *set = ip_set_rcu_get(par->net, index);
|
||||
struct ip_set *set = ip_set_rcu_get(xt_net(par), index);
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(!set);
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
|
|||
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
|
||||
e.ip &= ip_set_netmask(e.cidr);
|
||||
|
||||
#define IFACE(dir) (par->dir ? par->dir->name : "")
|
||||
#define IFACE(dir) (par->state->dir ? par->state->dir->name : "")
|
||||
#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC)
|
||||
|
||||
if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue