Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Browse files Browse the repository at this point in the history
Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

The following patchset contains Netfilter updates for your net-next
tree. Basically, improvements for the packet rejection infrastructure,
deprecation of CLUSTERIP, cleanups for nf_tables and some untangling for
br_netfilter. More specifically they are:

1) Send packet to reset flow if checksum is valid, from Florian Westphal.

2) Fix nf_tables reject bridge from the input chain, also from Florian.

3) Deprecate the CLUSTERIP target, the cluster match supersedes it in
   functionality and it's known to have problems.

4) A couple of cleanups for nf_tables rule tracing infrastructure, from
   Patrick McHardy.

5) Another cleanup to place transaction declarations at the bottom of
   nf_tables.h, also from Patrick.

6) Consolidate Kconfig dependencies wrt. NF_TABLES.

7) Limit table names to 32 bytes in nf_tables.

8) mac header copying in bridge netfilter is already required when
   calling ip_fragment(), from Florian Westphal.

9) move nf_bridge_update_protocol() to br_netfilter.c, also from
   Florian.

10) Small refactor in br_netfilter in the transmission path, again from
    Florian.

11) Move br_nf_pre_routing_finish_bridge_slow() to br_netfilter.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Mar 9, 2015
2 parents 26c459a + e5de75b commit 5428aef
Show file tree
Hide file tree
Showing 22 changed files with 412 additions and 289 deletions.
51 changes: 0 additions & 51 deletions include/linux/netfilter_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,44 +36,6 @@ static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
}
}

static inline void nf_bridge_update_protocol(struct sk_buff *skb)
{
if (skb->nf_bridge->mask & BRNF_8021Q)
skb->protocol = htons(ETH_P_8021Q);
else if (skb->nf_bridge->mask & BRNF_PPPoE)
skb->protocol = htons(ETH_P_PPP_SES);
}

/* Fill in the header for fragmented IP packets handled by
* the IPv4 connection tracking code.
*
* Only used in br_forward.c
*/
static inline int nf_bridge_copy_header(struct sk_buff *skb)
{
int err;
unsigned int header_size;

nf_bridge_update_protocol(skb);
header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
err = skb_cow_head(skb, header_size);
if (err)
return err;

skb_copy_to_linear_data_offset(skb, -header_size,
skb->nf_bridge->data, header_size);
__skb_push(skb, nf_bridge_encap_header_len(skb));
return 0;
}

static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb)
{
if (skb->nf_bridge &&
skb->nf_bridge->mask & (BRNF_BRIDGED | BRNF_BRIDGED_DNAT))
return nf_bridge_copy_header(skb);
return 0;
}

static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
{
if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE))
Expand All @@ -82,18 +44,6 @@ static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
}

int br_handle_frame_finish(struct sk_buff *skb);
/* Only used in br_device.c */
static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge = skb->nf_bridge;

skb_pull(skb, ETH_HLEN);
nf_bridge->mask ^= BRNF_BRIDGED_DNAT;
skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN),
skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
skb->dev = nf_bridge->physindev;
return br_handle_frame_finish(skb);
}

/* This is called by the IP fragmenting code and it ensures there is
* enough room for the encapsulating header (if there is one). */
Expand All @@ -119,7 +69,6 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb)
}

#else
#define nf_bridge_maybe_copy_header(skb) (0)
#define nf_bridge_pad(skb) (0)
#define br_drop_fake_rtable(skb) do { } while (0)
#endif /* CONFIG_BRIDGE_NETFILTER */
Expand Down
6 changes: 1 addition & 5 deletions include/net/netfilter/ipv4/nf_reject.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
#include <net/ip.h>
#include <net/icmp.h>

static inline void nf_send_unreach(struct sk_buff *skb_in, int code)
{
icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
}

void nf_send_unreach(struct sk_buff *skb_in, int code, int hook);
void nf_send_reset(struct sk_buff *oldskb, int hook);

const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
Expand Down
11 changes: 2 additions & 9 deletions include/net/netfilter/ipv6/nf_reject.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,8 @@

#include <linux/icmpv6.h>

static inline void
nf_send_unreach6(struct net *net, struct sk_buff *skb_in, unsigned char code,
unsigned int hooknum)
{
if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
skb_in->dev = net->loopback_dev;

icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0);
}
void nf_send_unreach6(struct net *net, struct sk_buff *skb_in, unsigned char code,
unsigned int hooknum);

void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook);

Expand Down
176 changes: 88 additions & 88 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,74 +393,6 @@ struct nft_rule {
__attribute__((aligned(__alignof__(struct nft_expr))));
};

/**
* struct nft_trans - nf_tables object update in transaction
*
* @list: used internally
* @msg_type: message type
* @ctx: transaction context
* @data: internal information related to the transaction
*/
struct nft_trans {
struct list_head list;
int msg_type;
struct nft_ctx ctx;
char data[0];
};

struct nft_trans_rule {
struct nft_rule *rule;
};

#define nft_trans_rule(trans) \
(((struct nft_trans_rule *)trans->data)->rule)

struct nft_trans_set {
struct nft_set *set;
u32 set_id;
};

#define nft_trans_set(trans) \
(((struct nft_trans_set *)trans->data)->set)
#define nft_trans_set_id(trans) \
(((struct nft_trans_set *)trans->data)->set_id)

struct nft_trans_chain {
bool update;
char name[NFT_CHAIN_MAXNAMELEN];
struct nft_stats __percpu *stats;
u8 policy;
};

#define nft_trans_chain_update(trans) \
(((struct nft_trans_chain *)trans->data)->update)
#define nft_trans_chain_name(trans) \
(((struct nft_trans_chain *)trans->data)->name)
#define nft_trans_chain_stats(trans) \
(((struct nft_trans_chain *)trans->data)->stats)
#define nft_trans_chain_policy(trans) \
(((struct nft_trans_chain *)trans->data)->policy)

struct nft_trans_table {
bool update;
bool enable;
};

#define nft_trans_table_update(trans) \
(((struct nft_trans_table *)trans->data)->update)
#define nft_trans_table_enable(trans) \
(((struct nft_trans_table *)trans->data)->enable)

struct nft_trans_elem {
struct nft_set *set;
struct nft_set_elem elem;
};

#define nft_trans_elem_set(trans) \
(((struct nft_trans_elem *)trans->data)->set)
#define nft_trans_elem(trans) \
(((struct nft_trans_elem *)trans->data)->elem)

static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
{
return (struct nft_expr *)&rule->data[0];
Expand Down Expand Up @@ -528,6 +460,25 @@ enum nft_chain_type {
NFT_CHAIN_T_MAX
};

/**
* struct nf_chain_type - nf_tables chain type info
*
* @name: name of the type
* @type: numeric identifier
* @family: address family
* @owner: module owner
* @hook_mask: mask of valid hooks
* @hooks: hookfn overrides
*/
struct nf_chain_type {
const char *name;
enum nft_chain_type type;
int family;
struct module *owner;
unsigned int hook_mask;
nf_hookfn *hooks[NF_MAX_HOOKS];
};

int nft_chain_validate_dependency(const struct nft_chain *chain,
enum nft_chain_type type);
int nft_chain_validate_hooks(const struct nft_chain *chain,
Expand Down Expand Up @@ -584,7 +535,7 @@ struct nft_table {
u64 hgenerator;
u32 use;
u16 flags;
char name[];
char name[NFT_TABLE_MAXNAMELEN];
};

/**
Expand Down Expand Up @@ -614,25 +565,6 @@ struct nft_af_info {
int nft_register_afinfo(struct net *, struct nft_af_info *);
void nft_unregister_afinfo(struct nft_af_info *);

/**
* struct nf_chain_type - nf_tables chain type info
*
* @name: name of the type
* @type: numeric identifier
* @family: address family
* @owner: module owner
* @hook_mask: mask of valid hooks
* @hooks: hookfn overrides
*/
struct nf_chain_type {
const char *name;
enum nft_chain_type type;
int family;
struct module *owner;
unsigned int hook_mask;
nf_hookfn *hooks[NF_MAX_HOOKS];
};

int nft_register_chain_type(const struct nf_chain_type *);
void nft_unregister_chain_type(const struct nf_chain_type *);

Expand All @@ -657,4 +589,72 @@ void nft_unregister_expr(struct nft_expr_type *);
#define MODULE_ALIAS_NFT_SET() \
MODULE_ALIAS("nft-set")

/**
* struct nft_trans - nf_tables object update in transaction
*
* @list: used internally
* @msg_type: message type
* @ctx: transaction context
* @data: internal information related to the transaction
*/
struct nft_trans {
struct list_head list;
int msg_type;
struct nft_ctx ctx;
char data[0];
};

struct nft_trans_rule {
struct nft_rule *rule;
};

#define nft_trans_rule(trans) \
(((struct nft_trans_rule *)trans->data)->rule)

struct nft_trans_set {
struct nft_set *set;
u32 set_id;
};

#define nft_trans_set(trans) \
(((struct nft_trans_set *)trans->data)->set)
#define nft_trans_set_id(trans) \
(((struct nft_trans_set *)trans->data)->set_id)

struct nft_trans_chain {
bool update;
char name[NFT_CHAIN_MAXNAMELEN];
struct nft_stats __percpu *stats;
u8 policy;
};

#define nft_trans_chain_update(trans) \
(((struct nft_trans_chain *)trans->data)->update)
#define nft_trans_chain_name(trans) \
(((struct nft_trans_chain *)trans->data)->name)
#define nft_trans_chain_stats(trans) \
(((struct nft_trans_chain *)trans->data)->stats)
#define nft_trans_chain_policy(trans) \
(((struct nft_trans_chain *)trans->data)->policy)

struct nft_trans_table {
bool update;
bool enable;
};

#define nft_trans_table_update(trans) \
(((struct nft_trans_table *)trans->data)->update)
#define nft_trans_table_enable(trans) \
(((struct nft_trans_table *)trans->data)->enable)

struct nft_trans_elem {
struct nft_set *set;
struct nft_set_elem elem;
};

#define nft_trans_elem_set(trans) \
(((struct nft_trans_elem *)trans->data)->set)
#define nft_trans_elem(trans) \
(((struct nft_trans_elem *)trans->data)->elem)

#endif /* _NET_NF_TABLES_H */
1 change: 1 addition & 0 deletions include/net/netns/x_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ struct ebt_table;
struct netns_xt {
struct list_head tables[NFPROTO_NUMPROTO];
bool notrack_deprecated_warning;
bool clusterip_deprecated_warning;
#if defined(CONFIG_BRIDGE_NF_EBTABLES) || \
defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE)
struct ebt_table *broute_table;
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _LINUX_NF_TABLES_H
#define _LINUX_NF_TABLES_H

#define NFT_TABLE_MAXNAMELEN 32
#define NFT_CHAIN_MAXNAMELEN 32
#define NFT_USERDATA_MAXLEN 256

Expand Down
5 changes: 1 addition & 4 deletions net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
u16 vid = 0;

rcu_read_lock();
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) {
br_nf_pre_routing_finish_bridge_slow(skb);
if (br_nf_prerouting_finish_bridge(skb)) {
rcu_read_unlock();
return NETDEV_TX_OK;
}
#endif

u64_stats_update_begin(&brstats->syncp);
brstats->tx_packets++;
Expand Down
4 changes: 1 addition & 3 deletions net/bridge/br_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ static inline int should_deliver(const struct net_bridge_port *p,

int br_dev_queue_push_xmit(struct sk_buff *skb)
{
/* ip_fragment doesn't copy the MAC header */
if (nf_bridge_maybe_copy_header(skb) ||
!is_skb_forwardable(skb->dev, skb)) {
if (!is_skb_forwardable(skb->dev, skb)) {
kfree_skb(skb);
} else {
skb_push(skb, ETH_HLEN);
Expand Down
Loading

0 comments on commit 5428aef

Please sign in to comment.