bridge: eliminate call by reference
Change the bridging hook to be simple function with return value rather than modifying the skb argument. This could generate better code and is cleaner. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
This commit is contained in:

committed by
David S. Miller

parent
604763722c
commit
6229e362dd
@@ -105,7 +105,8 @@ struct __fdb_entry
|
|||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *));
|
extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *));
|
||||||
extern int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);
|
extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
|
||||||
|
struct sk_buff *skb);
|
||||||
extern int (*br_should_route_hook)(struct sk_buff **pskb);
|
extern int (*br_should_route_hook)(struct sk_buff **pskb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -121,13 +121,11 @@ static inline int is_link_local(const unsigned char *dest)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Called via br_handle_frame_hook.
|
* Called via br_handle_frame_hook.
|
||||||
* Return 0 if *pskb should be processed furthur
|
* Return NULL if skb is handled
|
||||||
* 1 if *pskb is handled
|
|
||||||
* note: already called with rcu_read_lock (preempt_disabled)
|
* note: already called with rcu_read_lock (preempt_disabled)
|
||||||
*/
|
*/
|
||||||
int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
|
struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = *pskb;
|
|
||||||
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
||||||
|
|
||||||
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
|
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
|
||||||
@@ -135,15 +133,15 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
|
|||||||
|
|
||||||
if (unlikely(is_link_local(dest))) {
|
if (unlikely(is_link_local(dest))) {
|
||||||
skb->pkt_type = PACKET_HOST;
|
skb->pkt_type = PACKET_HOST;
|
||||||
return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
|
|
||||||
NULL, br_handle_local_finish) != 0;
|
return (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
|
||||||
|
NULL, br_handle_local_finish) == 0) ? skb : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
|
if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
|
||||||
if (br_should_route_hook) {
|
if (br_should_route_hook) {
|
||||||
if (br_should_route_hook(pskb))
|
if (br_should_route_hook(&skb))
|
||||||
return 0;
|
return skb;
|
||||||
skb = *pskb;
|
|
||||||
dest = eth_hdr(skb)->h_dest;
|
dest = eth_hdr(skb)->h_dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,10 +150,10 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
|
|||||||
|
|
||||||
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
|
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
|
||||||
br_handle_frame_finish);
|
br_handle_frame_finish);
|
||||||
return 1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return 1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@@ -182,7 +182,8 @@ extern void br_features_recompute(struct net_bridge *br);
|
|||||||
|
|
||||||
/* br_input.c */
|
/* br_input.c */
|
||||||
extern int br_handle_frame_finish(struct sk_buff *skb);
|
extern int br_handle_frame_finish(struct sk_buff *skb);
|
||||||
extern int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb);
|
extern struct sk_buff *br_handle_frame(struct net_bridge_port *p,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
|
||||||
/* br_ioctl.c */
|
/* br_ioctl.c */
|
||||||
extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||||
|
@@ -1687,31 +1687,37 @@ static inline int deliver_skb(struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
|
#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
|
||||||
int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);
|
/* These hooks defined here for ATM */
|
||||||
struct net_bridge;
|
struct net_bridge;
|
||||||
struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
|
struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
|
||||||
unsigned char *addr);
|
unsigned char *addr);
|
||||||
void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
|
void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent) __read_mostly;
|
||||||
|
|
||||||
static __inline__ int handle_bridge(struct sk_buff **pskb,
|
/*
|
||||||
struct packet_type **pt_prev, int *ret,
|
* If bridge module is loaded call bridging hook.
|
||||||
struct net_device *orig_dev)
|
* returns NULL if packet was consumed.
|
||||||
|
*/
|
||||||
|
struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
|
||||||
|
struct sk_buff *skb) __read_mostly;
|
||||||
|
static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
|
||||||
|
struct packet_type **pt_prev, int *ret,
|
||||||
|
struct net_device *orig_dev)
|
||||||
{
|
{
|
||||||
struct net_bridge_port *port;
|
struct net_bridge_port *port;
|
||||||
|
|
||||||
if ((*pskb)->pkt_type == PACKET_LOOPBACK ||
|
if (skb->pkt_type == PACKET_LOOPBACK ||
|
||||||
(port = rcu_dereference((*pskb)->dev->br_port)) == NULL)
|
(port = rcu_dereference(skb->dev->br_port)) == NULL)
|
||||||
return 0;
|
return skb;
|
||||||
|
|
||||||
if (*pt_prev) {
|
if (*pt_prev) {
|
||||||
*ret = deliver_skb(*pskb, *pt_prev, orig_dev);
|
*ret = deliver_skb(skb, *pt_prev, orig_dev);
|
||||||
*pt_prev = NULL;
|
*pt_prev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return br_handle_frame_hook(port, pskb);
|
return br_handle_frame_hook(port, skb);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define handle_bridge(skb, pt_prev, ret, orig_dev) (0)
|
#define handle_bridge(skb, pt_prev, ret, orig_dev) (skb)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CLS_ACT
|
#ifdef CONFIG_NET_CLS_ACT
|
||||||
@@ -1818,7 +1824,8 @@ int netif_receive_skb(struct sk_buff *skb)
|
|||||||
ncls:
|
ncls:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
|
skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
|
||||||
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
type = skb->protocol;
|
type = skb->protocol;
|
||||||
|
Reference in New Issue
Block a user