Skip to content

Commit 6229e36

Browse files
Stephen HemmingerDavid S. Miller
authored andcommitted
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 <[email protected]>
1 parent 6047637 commit 6229e36

File tree

4 files changed

+32
-25
lines changed

4 files changed

+32
-25
lines changed

include/linux/if_bridge.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ struct __fdb_entry
105105
#include <linux/netdevice.h>
106106

107107
extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *));
108-
extern int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);
108+
extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
109+
struct sk_buff *skb);
109110
extern int (*br_should_route_hook)(struct sk_buff **pskb);
110111

111112
#endif

net/bridge/br_input.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,29 +121,27 @@ static inline int is_link_local(const unsigned char *dest)
121121

122122
/*
123123
* Called via br_handle_frame_hook.
124-
* Return 0 if *pskb should be processed furthur
125-
* 1 if *pskb is handled
124+
* Return NULL if skb is handled
126125
* note: already called with rcu_read_lock (preempt_disabled)
127126
*/
128-
int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
127+
struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
129128
{
130-
struct sk_buff *skb = *pskb;
131129
const unsigned char *dest = eth_hdr(skb)->h_dest;
132130

133131
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
134132
goto err;
135133

136134
if (unlikely(is_link_local(dest))) {
137135
skb->pkt_type = PACKET_HOST;
138-
return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
139-
NULL, br_handle_local_finish) != 0;
136+
137+
return (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
138+
NULL, br_handle_local_finish) == 0) ? skb : NULL;
140139
}
141140

142141
if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
143142
if (br_should_route_hook) {
144-
if (br_should_route_hook(pskb))
145-
return 0;
146-
skb = *pskb;
143+
if (br_should_route_hook(&skb))
144+
return skb;
147145
dest = eth_hdr(skb)->h_dest;
148146
}
149147

@@ -152,10 +150,10 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
152150

153151
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
154152
br_handle_frame_finish);
155-
return 1;
153+
return NULL;
156154
}
157155

158156
err:
159157
kfree_skb(skb);
160-
return 1;
158+
return NULL;
161159
}

net/bridge/br_private.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ extern void br_features_recompute(struct net_bridge *br);
182182

183183
/* br_input.c */
184184
extern int br_handle_frame_finish(struct sk_buff *skb);
185-
extern int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb);
185+
extern struct sk_buff *br_handle_frame(struct net_bridge_port *p,
186+
struct sk_buff *skb);
186187

187188
/* br_ioctl.c */
188189
extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);

net/core/dev.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,31 +1687,37 @@ static inline int deliver_skb(struct sk_buff *skb,
16871687
}
16881688

16891689
#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
1690-
int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);
1690+
/* These hooks defined here for ATM */
16911691
struct net_bridge;
16921692
struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
16931693
unsigned char *addr);
1694-
void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
1694+
void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent) __read_mostly;
16951695

1696-
static __inline__ int handle_bridge(struct sk_buff **pskb,
1697-
struct packet_type **pt_prev, int *ret,
1698-
struct net_device *orig_dev)
1696+
/*
1697+
* If bridge module is loaded call bridging hook.
1698+
* returns NULL if packet was consumed.
1699+
*/
1700+
struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
1701+
struct sk_buff *skb) __read_mostly;
1702+
static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
1703+
struct packet_type **pt_prev, int *ret,
1704+
struct net_device *orig_dev)
16991705
{
17001706
struct net_bridge_port *port;
17011707

1702-
if ((*pskb)->pkt_type == PACKET_LOOPBACK ||
1703-
(port = rcu_dereference((*pskb)->dev->br_port)) == NULL)
1704-
return 0;
1708+
if (skb->pkt_type == PACKET_LOOPBACK ||
1709+
(port = rcu_dereference(skb->dev->br_port)) == NULL)
1710+
return skb;
17051711

17061712
if (*pt_prev) {
1707-
*ret = deliver_skb(*pskb, *pt_prev, orig_dev);
1713+
*ret = deliver_skb(skb, *pt_prev, orig_dev);
17081714
*pt_prev = NULL;
17091715
}
17101716

1711-
return br_handle_frame_hook(port, pskb);
1717+
return br_handle_frame_hook(port, skb);
17121718
}
17131719
#else
1714-
#define handle_bridge(skb, pt_prev, ret, orig_dev) (0)
1720+
#define handle_bridge(skb, pt_prev, ret, orig_dev) (skb)
17151721
#endif
17161722

17171723
#ifdef CONFIG_NET_CLS_ACT
@@ -1818,7 +1824,8 @@ int netif_receive_skb(struct sk_buff *skb)
18181824
ncls:
18191825
#endif
18201826

1821-
if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
1827+
skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
1828+
if (!skb)
18221829
goto out;
18231830

18241831
type = skb->protocol;

0 commit comments

Comments
 (0)