Skip to content

Commit

Permalink
netfilter: Pass net into okfn
Browse files Browse the repository at this point in the history
This is immediately motivated by the bridge code that chains functions that
call into netfilter.  Without passing net into the okfns the bridge code would
need to guess about the best expression for the network namespace to process
packets in.

As net is frequently one of the first things computed in continuation functions
after netfilter has done it's job passing in the desired network namespace is in
many cases a code simplification.

To support this change the function dst_output_okfn is introduced to
simplify passing dst_output as an okfn.  For the moment dst_output_okfn
just silently drops the struct net.

Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
ebiederm authored and davem330 committed Sep 18, 2015
1 parent 9dff2c9 commit 0c4b51f
Show file tree
Hide file tree
Showing 37 changed files with 95 additions and 94 deletions.
2 changes: 1 addition & 1 deletion drivers/net/vrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
}

/* modelled after ip_finish_output2 */
static int vrf_finish_output(struct sock *sk, struct sk_buff *skb)
static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct rtable *rt = (struct rtable *)dst;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -2212,7 +2212,7 @@ int dev_open(struct net_device *dev);
int dev_close(struct net_device *dev);
int dev_close_many(struct list_head *head, bool unlink);
void dev_disable_lro(struct net_device *dev);
int dev_loopback_xmit(struct sock *sk, struct sk_buff *newskb);
int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *newskb);
int dev_queue_xmit(struct sk_buff *skb);
int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv);
int register_netdevice(struct net_device *dev);
Expand Down
26 changes: 14 additions & 12 deletions include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct nf_hook_state {
struct sock *sk;
struct net *net;
struct list_head *hook_list;
int (*okfn)(struct sock *, struct sk_buff *);
int (*okfn)(struct net *, struct sock *, struct sk_buff *);
};

static inline void nf_hook_state_init(struct nf_hook_state *p,
Expand All @@ -67,7 +67,7 @@ static inline void nf_hook_state_init(struct nf_hook_state *p,
struct net_device *outdev,
struct sock *sk,
struct net *net,
int (*okfn)(struct sock *, struct sk_buff *))
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
p->hook = hook;
p->thresh = thresh;
Expand Down Expand Up @@ -175,7 +175,7 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sock *, struct sk_buff *),
int (*okfn)(struct net *, struct sock *, struct sk_buff *),
int thresh)
{
struct list_head *hook_list = &net->nf.hooks[pf][hook];
Expand All @@ -193,7 +193,7 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net,
struct sock *sk, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sock *, struct sk_buff *))
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
return nf_hook_thresh(pf, hook, net, sk, skb, indev, outdev, okfn, INT_MIN);
}
Expand All @@ -219,31 +219,33 @@ static inline int
NF_HOOK_THRESH(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
struct sk_buff *skb, struct net_device *in,
struct net_device *out,
int (*okfn)(struct sock *, struct sk_buff *), int thresh)
int (*okfn)(struct net *, struct sock *, struct sk_buff *),
int thresh)
{
int ret = nf_hook_thresh(pf, hook, net, sk, skb, in, out, okfn, thresh);
if (ret == 1)
ret = okfn(sk, skb);
ret = okfn(net, sk, skb);
return ret;
}

static inline int
NF_HOOK_COND(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
struct sk_buff *skb, struct net_device *in, struct net_device *out,
int (*okfn)(struct sock *, struct sk_buff *), bool cond)
int (*okfn)(struct net *, struct sock *, struct sk_buff *),
bool cond)
{
int ret;

if (!cond ||
((ret = nf_hook_thresh(pf, hook, net, sk, skb, in, out, okfn, INT_MIN)) == 1))
ret = okfn(sk, skb);
ret = okfn(net, sk, skb);
return ret;
}

static inline int
NF_HOOK(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk, struct sk_buff *skb,
struct net_device *in, struct net_device *out,
int (*okfn)(struct sock *, struct sk_buff *))
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
return NF_HOOK_THRESH(pf, hook, net, sk, skb, in, out, okfn, INT_MIN);
}
Expand Down Expand Up @@ -345,12 +347,12 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
}

#else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, net, sk, skb, indev, outdev, okfn) (okfn)(sk, skb)
#define NF_HOOK_COND(pf, hook, net, sk, skb, indev, outdev, okfn, cond) (okfn)(sk, skb)
#define NF_HOOK(pf, hook, net, sk, skb, indev, outdev, okfn) (okfn)(net, sk, skb)
#define NF_HOOK_COND(pf, hook, net, sk, skb, indev, outdev, okfn, cond) (okfn)(net, sk, skb)
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net,
struct sock *sk, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sock *, struct sk_buff *))
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion include/linux/netfilter_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ enum nf_br_hook_priorities {

#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)

int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb);
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);

static inline void br_drop_fake_rtable(struct sk_buff *skb)
{
Expand Down
6 changes: 3 additions & 3 deletions include/net/dn_neigh.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ struct dn_neigh {

void dn_neigh_init(void);
void dn_neigh_cleanup(void);
int dn_neigh_router_hello(struct sock *sk, struct sk_buff *skb);
int dn_neigh_endnode_hello(struct sock *sk, struct sk_buff *skb);
int dn_neigh_router_hello(struct net *net, struct sock *sk, struct sk_buff *skb);
int dn_neigh_endnode_hello(struct net *net, struct sock *sk, struct sk_buff *skb);
void dn_neigh_pointopoint_hello(struct sk_buff *skb);
int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n);
int dn_to_neigh_output(struct sock *sk, struct sk_buff *skb);
int dn_to_neigh_output(struct net *net, struct sock *sk, struct sk_buff *skb);

extern struct neigh_table dn_neigh_table;

Expand Down
4 changes: 4 additions & 0 deletions include/net/dst.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,10 @@ static inline int dst_output(struct sock *sk, struct sk_buff *skb)
{
return skb_dst(skb)->output(sk, skb);
}
static inline int dst_output_okfn(struct net *net, struct sock *sk, struct sk_buff *skb)
{
return dst_output(sk, skb);
}

/* Input packet from network to transport. */
static inline int dst_input(struct sk_buff *skb)
Expand Down
2 changes: 1 addition & 1 deletion include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ static inline u8 ip6_tclass(__be32 flowinfo)
int ipv6_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);

int ip6_rcv_finish(struct sock *sk, struct sk_buff *skb);
int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb);

/*
* upper-layer output functions
Expand Down
2 changes: 1 addition & 1 deletion include/net/netfilter/br_netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static inline void nf_bridge_push_encap_header(struct sk_buff *skb)
skb->network_header -= len;
}

int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb);
int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_buff *skb);

static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
{
Expand Down
5 changes: 2 additions & 3 deletions net/bridge/br_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static inline int should_deliver(const struct net_bridge_port *p,
p->state == BR_STATE_FORWARDING;
}

int br_dev_queue_push_xmit(struct sock *sk, struct sk_buff *skb)
int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
{
if (!is_skb_forwardable(skb->dev, skb))
goto drop;
Expand Down Expand Up @@ -65,9 +65,8 @@ int br_dev_queue_push_xmit(struct sock *sk, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit);

int br_forward_finish(struct sock *sk, struct sk_buff *skb)
int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net *net = dev_net(skb->dev);
return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING,
net, sk, skb, NULL, skb->dev,
br_dev_queue_push_xmit);
Expand Down
7 changes: 4 additions & 3 deletions net/bridge/br_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
EXPORT_SYMBOL(br_should_route_hook);

static int br_netif_receive_skb(struct sock *sk, struct sk_buff *skb)
static int
br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb)
{
return netif_receive_skb(skb);
}
Expand Down Expand Up @@ -125,7 +126,7 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
}

/* note: already called with rcu_read_lock */
int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb)
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
const unsigned char *dest = eth_hdr(skb)->h_dest;
struct net_bridge_port *p = br_port_get_rcu(skb->dev);
Expand Down Expand Up @@ -213,7 +214,7 @@ int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb)
EXPORT_SYMBOL_GPL(br_handle_frame_finish);

/* note: already called with rcu_read_lock */
static int br_handle_local_finish(struct sock *sk, struct sk_buff *skb)
static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net_bridge_port *p = br_port_get_rcu(skb->dev);
u16 vid = 0;
Expand Down
21 changes: 9 additions & 12 deletions net/bridge/br_netfilter_hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ void nf_bridge_update_protocol(struct sk_buff *skb)
* don't, we use the neighbour framework to find out. In both cases, we make
* sure that br_handle_frame_finish() is called afterwards.
*/
int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct neighbour *neigh;
struct dst_entry *dst;
Expand All @@ -273,7 +273,7 @@ int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
if (neigh->hh.hh_len) {
neigh_hh_bridge(&neigh->hh, skb);
skb->dev = nf_bridge->physindev;
ret = br_handle_frame_finish(sk, skb);
ret = br_handle_frame_finish(net, sk, skb);
} else {
/* the neighbour function below overwrites the complete
* MAC header, so we save the Ethernet source address and
Expand Down Expand Up @@ -342,11 +342,10 @@ br_nf_ipv4_daddr_was_changed(const struct sk_buff *skb,
* device, we proceed as if ip_route_input() succeeded. If it differs from the
* logical bridge port or if ip_route_output_key() fails we drop the packet.
*/
static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
struct iphdr *iph = ip_hdr(skb);
struct net *net = dev_net(dev);
struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
struct rtable *rt;
int err;
Expand Down Expand Up @@ -536,10 +535,9 @@ static unsigned int br_nf_local_in(const struct nf_hook_ops *ops,
}

/* PF_BRIDGE/FORWARD *************************************************/
static int br_nf_forward_finish(struct sock *sk, struct sk_buff *skb)
static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
struct net *net = dev_net(skb->dev);
struct net_device *in;

if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) {
Expand Down Expand Up @@ -692,7 +690,7 @@ static int br_nf_push_frag_xmit(struct net *net, struct sock *sk, struct sk_buff
__skb_push(skb, data->encap_size);

nf_bridge_info_free(skb);
return br_dev_queue_push_xmit(sk, skb);
return br_dev_queue_push_xmit(net, sk, skb);
}
static int br_nf_push_frag_xmit_sk(struct sock *sk, struct sk_buff *skb)
{
Expand Down Expand Up @@ -728,17 +726,16 @@ static unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
return 0;
}

static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb)
static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge;
unsigned int mtu_reserved;
struct net *net = dev_net(skb_dst(skb)->dev);

mtu_reserved = nf_bridge_mtu_reduction(skb);

if (skb_is_gso(skb) || skb->len + mtu_reserved <= skb->dev->mtu) {
nf_bridge_info_free(skb);
return br_dev_queue_push_xmit(sk, skb);
return br_dev_queue_push_xmit(net, sk, skb);
}

nf_bridge = nf_bridge_info_get(skb);
Expand Down Expand Up @@ -797,7 +794,7 @@ static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb)
}
#endif
nf_bridge_info_free(skb);
return br_dev_queue_push_xmit(sk, skb);
return br_dev_queue_push_xmit(net, sk, skb);
drop:
kfree_skb(skb);
return 0;
Expand Down Expand Up @@ -887,7 +884,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
skb->dev = nf_bridge->physindev;

nf_bridge->physoutdev = NULL;
br_handle_frame_finish(NULL, skb);
br_handle_frame_finish(dev_net(skb->dev), NULL, skb);
}

static int br_nf_dev_xmit(struct sk_buff *skb)
Expand Down
3 changes: 1 addition & 2 deletions net/bridge/br_netfilter_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,11 @@ br_nf_ipv6_daddr_was_changed(const struct sk_buff *skb,
* for br_nf_pre_routing_finish(), same logic is used here but
* equivalent IPv6 function ip6_route_input() called indirectly.
*/
static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb)
static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
struct rtable *rt;
struct net_device *dev = skb->dev;
struct net *net = dev_net(dev);
const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();

nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size;
Expand Down
6 changes: 3 additions & 3 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,10 +413,10 @@ int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,

/* br_forward.c */
void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb);
int br_dev_queue_push_xmit(struct sock *sk, struct sk_buff *skb);
int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb);
void br_forward(const struct net_bridge_port *to,
struct sk_buff *skb, struct sk_buff *skb0);
int br_forward_finish(struct sock *sk, struct sk_buff *skb);
int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast);
void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
struct sk_buff *skb2, bool unicast);
Expand All @@ -434,7 +434,7 @@ void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
void br_manage_promisc(struct net_bridge *br);

/* br_input.c */
int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb);
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
rx_handler_result_t br_handle_frame(struct sk_buff **pskb);

static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
Expand Down
3 changes: 2 additions & 1 deletion net/bridge/br_stp_bpdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@

#define LLC_RESERVE sizeof(struct llc_pdu_un)

static int br_send_bpdu_finish(struct sock *sk, struct sk_buff *skb)
static int br_send_bpdu_finish(struct net *net, struct sock *sk,
struct sk_buff *skb)
{
return dev_queue_xmit(skb);
}
Expand Down
4 changes: 3 additions & 1 deletion net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2915,9 +2915,11 @@ EXPORT_SYMBOL(xmit_recursion);

/**
* dev_loopback_xmit - loop back @skb
* @net: network namespace this loopback is happening in
* @sk: sk needed to be a netfilter okfn
* @skb: buffer to transmit
*/
int dev_loopback_xmit(struct sock *sk, struct sk_buff *skb)
int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
{
skb_reset_mac_header(skb);
__skb_pull(skb, skb_network_offset(skb));
Expand Down
8 changes: 4 additions & 4 deletions net/decnet/dn_neigh.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb)
return err;
}

static int dn_neigh_output_packet(struct sock *sk, struct sk_buff *skb)
static int dn_neigh_output_packet(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct dn_route *rt = (struct dn_route *)dst;
Expand Down Expand Up @@ -334,7 +334,7 @@ static int dn_phase3_output(struct neighbour *neigh, struct sock *sk,
dn_neigh_output_packet);
}

int dn_to_neigh_output(struct sock *sk, struct sk_buff *skb)
int dn_to_neigh_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct dn_route *rt = (struct dn_route *) dst;
Expand Down Expand Up @@ -378,7 +378,7 @@ void dn_neigh_pointopoint_hello(struct sk_buff *skb)
/*
* Ethernet router hello message received
*/
int dn_neigh_router_hello(struct sock *sk, struct sk_buff *skb)
int dn_neigh_router_hello(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct rtnode_hello_message *msg = (struct rtnode_hello_message *)skb->data;

Expand Down Expand Up @@ -440,7 +440,7 @@ int dn_neigh_router_hello(struct sock *sk, struct sk_buff *skb)
/*
* Endnode hello message received
*/
int dn_neigh_endnode_hello(struct sock *sk, struct sk_buff *skb)
int dn_neigh_endnode_hello(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct endnode_hello_message *msg = (struct endnode_hello_message *)skb->data;
struct neighbour *neigh;
Expand Down
Loading

0 comments on commit 0c4b51f

Please sign in to comment.