|
@@ -311,9 +311,10 @@ drop:
|
|
|
static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
|
{
|
|
|
const struct iphdr *iph = ip_hdr(skb);
|
|
|
- struct rtable *rt;
|
|
|
+ int (*edemux)(struct sk_buff *skb);
|
|
|
struct net_device *dev = skb->dev;
|
|
|
- void (*edemux)(struct sk_buff *skb);
|
|
|
+ struct rtable *rt;
|
|
|
+ int err;
|
|
|
|
|
|
/* if ingress device is enslaved to an L3 master device pass the
|
|
|
* skb to its handler for processing
|
|
@@ -331,7 +332,9 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
|
|
|
|
ipprot = rcu_dereference(inet_protos[protocol]);
|
|
|
if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) {
|
|
|
- edemux(skb);
|
|
|
+ err = edemux(skb);
|
|
|
+ if (unlikely(err))
|
|
|
+ goto drop_error;
|
|
|
/* must reload iph, skb->head might have changed */
|
|
|
iph = ip_hdr(skb);
|
|
|
}
|
|
@@ -342,13 +345,10 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
|
* how the packet travels inside Linux networking.
|
|
|
*/
|
|
|
if (!skb_valid_dst(skb)) {
|
|
|
- int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
|
|
|
- iph->tos, dev);
|
|
|
- if (unlikely(err)) {
|
|
|
- if (err == -EXDEV)
|
|
|
- __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER);
|
|
|
- goto drop;
|
|
|
- }
|
|
|
+ err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
|
|
|
+ iph->tos, dev);
|
|
|
+ if (unlikely(err))
|
|
|
+ goto drop_error;
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_IP_ROUTE_CLASSID
|
|
@@ -399,6 +399,11 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|
|
drop:
|
|
|
kfree_skb(skb);
|
|
|
return NET_RX_DROP;
|
|
|
+
|
|
|
+drop_error:
|
|
|
+ if (err == -EXDEV)
|
|
|
+ __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER);
|
|
|
+ goto drop;
|
|
|
}
|
|
|
|
|
|
/*
|