Loading net/ipv4/ip_input.c +54 −39 Original line number Diff line number Diff line Loading @@ -279,37 +279,11 @@ int ip_local_deliver(struct sk_buff *skb) ip_local_deliver_finish); } static inline int ip_rcv_finish(struct sk_buff *skb) static inline int ip_rcv_options(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct iphdr *iph = skb->nh.iph; int err; /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (skb->dst == NULL) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { if (err == -EHOSTUNREACH) IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); goto drop; } } #ifdef CONFIG_NET_CLS_ROUTE if (skb->dst->tclassid) { struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id(); u32 idx = skb->dst->tclassid; st[idx&0xFF].o_packets++; st[idx&0xFF].o_bytes+=skb->len; st[(idx>>16)&0xFF].i_packets++; st[(idx>>16)&0xFF].i_bytes+=skb->len; } #endif if (iph->ihl > 5) { struct ip_options *opt; struct iphdr *iph; struct net_device *dev = skb->dev; /* It looks as overkill, because not all IP options require packet mangling. Loading @@ -318,38 +292,79 @@ static inline int ip_rcv_finish(struct sk_buff *skb) and running sniffer is extremely rare condition. --ANK (980813) */ if (skb_cow(skb, skb_headroom(skb))) { IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); goto drop; } iph = skb->nh.iph; if (ip_options_compile(NULL, skb)) goto inhdr_error; if (ip_options_compile(NULL, skb)) { IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); goto drop; } opt = &(IPCB(skb)->opt); if (opt->srr) { if (unlikely(opt->srr)) { struct in_device *in_dev = in_dev_get(dev); if (in_dev) { if (!IN_DEV_SOURCE_ROUTE(in_dev)) { if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) printk(KERN_INFO "source route option %u.%u.%u.%u -> %u.%u.%u.%u\n", NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) printk(KERN_INFO "source route option " "%u.%u.%u.%u -> %u.%u.%u.%u\n", NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); in_dev_put(in_dev); goto drop; } in_dev_put(in_dev); } if (ip_options_rcv_srr(skb)) goto drop; } return 0; drop: return -1; } static inline int ip_rcv_finish(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct iphdr *iph = skb->nh.iph; int err; /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (skb->dst == NULL) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { if (err == -EHOSTUNREACH) IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); goto drop; } } #ifdef CONFIG_NET_CLS_ROUTE if (skb->dst->tclassid) { struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id(); u32 idx = skb->dst->tclassid; st[idx&0xFF].o_packets++; st[idx&0xFF].o_bytes+=skb->len; st[(idx>>16)&0xFF].i_packets++; st[(idx>>16)&0xFF].i_bytes+=skb->len; } #endif if (iph->ihl > 5 && ip_rcv_options(skb)) goto drop; return dst_input(skb); inhdr_error: IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); drop: kfree_skb(skb); return NET_RX_DROP; Loading Loading
net/ipv4/ip_input.c +54 −39 Original line number Diff line number Diff line Loading @@ -279,37 +279,11 @@ int ip_local_deliver(struct sk_buff *skb) ip_local_deliver_finish); } static inline int ip_rcv_finish(struct sk_buff *skb) static inline int ip_rcv_options(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct iphdr *iph = skb->nh.iph; int err; /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (skb->dst == NULL) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { if (err == -EHOSTUNREACH) IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); goto drop; } } #ifdef CONFIG_NET_CLS_ROUTE if (skb->dst->tclassid) { struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id(); u32 idx = skb->dst->tclassid; st[idx&0xFF].o_packets++; st[idx&0xFF].o_bytes+=skb->len; st[(idx>>16)&0xFF].i_packets++; st[(idx>>16)&0xFF].i_bytes+=skb->len; } #endif if (iph->ihl > 5) { struct ip_options *opt; struct iphdr *iph; struct net_device *dev = skb->dev; /* It looks as overkill, because not all IP options require packet mangling. Loading @@ -318,38 +292,79 @@ static inline int ip_rcv_finish(struct sk_buff *skb) and running sniffer is extremely rare condition. --ANK (980813) */ if (skb_cow(skb, skb_headroom(skb))) { IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); goto drop; } iph = skb->nh.iph; if (ip_options_compile(NULL, skb)) goto inhdr_error; if (ip_options_compile(NULL, skb)) { IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); goto drop; } opt = &(IPCB(skb)->opt); if (opt->srr) { if (unlikely(opt->srr)) { struct in_device *in_dev = in_dev_get(dev); if (in_dev) { if (!IN_DEV_SOURCE_ROUTE(in_dev)) { if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) printk(KERN_INFO "source route option %u.%u.%u.%u -> %u.%u.%u.%u\n", NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) printk(KERN_INFO "source route option " "%u.%u.%u.%u -> %u.%u.%u.%u\n", NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); in_dev_put(in_dev); goto drop; } in_dev_put(in_dev); } if (ip_options_rcv_srr(skb)) goto drop; } return 0; drop: return -1; } static inline int ip_rcv_finish(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct iphdr *iph = skb->nh.iph; int err; /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (skb->dst == NULL) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { if (err == -EHOSTUNREACH) IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); goto drop; } } #ifdef CONFIG_NET_CLS_ROUTE if (skb->dst->tclassid) { struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id(); u32 idx = skb->dst->tclassid; st[idx&0xFF].o_packets++; st[idx&0xFF].o_bytes+=skb->len; st[(idx>>16)&0xFF].i_packets++; st[(idx>>16)&0xFF].i_bytes+=skb->len; } #endif if (iph->ihl > 5 && ip_rcv_options(skb)) goto drop; return dst_input(skb); inhdr_error: IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); drop: kfree_skb(skb); return NET_RX_DROP; Loading