/*
* Called via br_handle_frame_hook.
- * Return 0 if *pskb should be processed furthur
- * 1 if *pskb is handled
+ * Return NULL if skb is handled
* 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;
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
if (unlikely(is_link_local(dest))) {
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 (br_should_route_hook) {
- if (br_should_route_hook(pskb))
- return 0;
- skb = *pskb;
+ if (br_should_route_hook(&skb))
+ return skb;
dest = eth_hdr(skb)->h_dest;
}
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
br_handle_frame_finish);
- return 1;
+ return NULL;
}
err:
kfree_skb(skb);
- return 1;
+ return NULL;
}
}
#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_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
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,
- struct net_device *orig_dev)
+/*
+ * If bridge module is loaded call bridging hook.
+ * 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;
- if ((*pskb)->pkt_type == PACKET_LOOPBACK ||
- (port = rcu_dereference((*pskb)->dev->br_port)) == NULL)
- return 0;
+ if (skb->pkt_type == PACKET_LOOPBACK ||
+ (port = rcu_dereference(skb->dev->br_port)) == NULL)
+ return skb;
if (*pt_prev) {
- *ret = deliver_skb(*pskb, *pt_prev, orig_dev);
+ *ret = deliver_skb(skb, *pt_prev, orig_dev);
*pt_prev = NULL;
}
- return br_handle_frame_hook(port, pskb);
+ return br_handle_frame_hook(port, skb);
}
#else
-#define handle_bridge(skb, pt_prev, ret, orig_dev) (0)
+#define handle_bridge(skb, pt_prev, ret, orig_dev) (skb)
#endif
#ifdef CONFIG_NET_CLS_ACT
ncls:
#endif
- if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
+ skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
+ if (!skb)
goto out;
type = skb->protocol;