Commit cf8cd3d1 authored by David S. Miller's avatar David S. Miller Committed by Dmitry Torokhov

Cset exclude: mashirle@us.ibm.com|ChangeSet|20040526204412|10895

parent 4d9d9fa9
......@@ -44,9 +44,6 @@
#define RTM_DELTFILTER (RTM_BASE+29)
#define RTM_GETTFILTER (RTM_BASE+30)
#define RTM_NEWIPSTATS (RTM_BASE+32)
#define RTM_GETIPSTATS (RTM_BASE+34)
#define RTM_NEWPREFIX (RTM_BASE+36)
#define RTM_GETPREFIX (RTM_BASE+38)
......@@ -640,23 +637,6 @@ enum
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
/********************************************************************
* IP mibs information
****/
struct ipstatsmsg
{
int ipstats_family;
int ipstats_ifindex;
};
enum
{
IPSTATS_IFNAME,
IPSTATS_COUNTERS,
};
#define IPSTATS_MAX IPSTATS_COUNTERS
/* SUMMARY: maximal rtattr understood by kernel */
......
......@@ -149,7 +149,6 @@ struct ifacaddr6
struct ipv6_devstat {
struct proc_dir_entry *proc_dir_entry;
DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
DEFINE_SNMP_STAT(struct ip_stats, ipv6);
};
struct inet6_dev
......
......@@ -116,44 +116,6 @@ DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
#define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field)
#define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field)
DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
/* new IPv6 MIB */
DECLARE_SNMP_STAT(struct ip_stats, ipv6_stats);
#define IPV6_INC_STATS(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(_idev->stats.ipv6, field); \
SNMP_INC_STATS(ipv6_stats, field); \
})
#define IPV6_INC_STATS_BH(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(_idev->stats.ipv6, field); \
SNMP_INC_STATS_BH(ipv6_stats, field); \
})
#define IPV6_INC_STATS_USER(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(_idev->stats.ipv6, field); \
SNMP_INC_STATS_USER(ipv6_stats, field); \
})
#define IPV6_ADD_STATS_BH(idev, field, addend) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_ADD_STATS_BH(_idev->stats.ipv6, field, addend); \
SNMP_ADD_STATS_BH(ipv6_stats, field, addend); \
})
#define IPV6_ADD_STATS_USER(idev, field, addend) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_ADD_STATS_USER(_idev->stats.ipv6, field, addend); \
SNMP_ADD_STATS_USER(ipv6_stats, field, addend); \
})
#define IPV6_ADD_STATS(idev, field, addend) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_ADD_STATS(_idev->stats.ipv6, field, addend); \
SNMP_ADD_STATS(ipv6_stats, field, addend); \
})
#define ICMP6_INC_STATS(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
......
......@@ -99,43 +99,6 @@ struct ipv6_mib
unsigned long __pad[0];
};
/*
* New IP MIBs from draft-ietf-ipv6-rfc2011-update-05.txt
*/
struct ip_stats
{
unsigned long ipStatsInReceives;
unsigned long ipStatsInOctets;
unsigned long ipStatsInHdrErrors;
unsigned long ipStatsInNoRoutes;
unsigned long ipStatsInAddrErrors;
unsigned long ipStatsInUnknownProtos;
unsigned long ipStatsInTruncatedPkts;
unsigned long ipStatsInForwDatagrams;
unsigned long ipStatsReasmReqds;
unsigned long ipStatsReasmOKs;
unsigned long ipStatsReasmFails;
unsigned long ipStatsInDiscards;
unsigned long ipStatsInDelivers;
unsigned long ipStatsOutRequests;
unsigned long ipStatsOutNoRoutes;
unsigned long ipStatsOutForwDatagrams;
unsigned long ipStatsOutDiscards;
unsigned long ipStatsOutFragReqds;
unsigned long ipStatsOutFragOKs;
unsigned long ipStatsOutFragFails;
unsigned long ipStatsOutFragCreates;
unsigned long ipStatsOutTransmits;
unsigned long ipStatsOutOctets;
unsigned long ipStatsInMcastPkts;
unsigned long ipStatsInMcastOctets;
unsigned long ipStatsOutMcastPkts;
unsigned long ipStatsOutMcastOctets;
unsigned long ipStatsInBcastPkts;
unsigned long ipStatsOutBcastPkts;
unsigned long __pad[0];
};
/*
* RFC 1213: MIB-II ICMP Group
* RFC 2011 (updates 1213): SNMPv2 MIB for IP: ICMP group
......@@ -372,8 +335,6 @@ struct linux_mib
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field++)
#define SNMP_DEC_STATS(mib, field) \
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field--)
#define SNMP_ADD_STATS(mib, field, addend) \
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field += addend)
#define SNMP_ADD_STATS_BH(mib, field, addend) \
(per_cpu_ptr(mib[0], smp_processor_id())->field += addend)
#define SNMP_ADD_STATS_USER(mib, field, addend) \
......
......@@ -2963,101 +2963,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC);
}
static unsigned long
fold_field(void *mib[], int offt)
{
unsigned long res = 0;
int i;
for (i = 0; i < NR_CPUS; i++) {
if (!cpu_possible(i))
continue;
res +=
*((unsigned long *) (((void *)per_cpu_ptr(mib[0], i)) +
offt));
res +=
*((unsigned long *) (((void *)per_cpu_ptr(mib[1], i)) +
offt));
}
return res;
}
static int inet6_fill_ipstats(struct sk_buff *skb, struct inet6_dev *idev,
u32 pid, u32 seq, int event)
{
struct ipstatsmsg *r;
struct nlmsghdr *nlh;
unsigned char *b = skb->tail;
struct ip_stats ipstats;
unsigned long *array;
int i, num;
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
if (pid)
nlh->nlmsg_flags |= NLM_F_MULTI;
r = NLMSG_DATA(nlh);
r->ipstats_family = AF_INET6;
r->ipstats_ifindex = 0;
num = offsetof(struct ip_stats, __pad) / sizeof(unsigned long);
memset(&ipstats , 0, sizeof(struct ip_stats));
array = (unsigned long *)&ipstats;
if (idev == NULL) {
/* fill IP mibs system statistics */
RTA_PUT(skb, IPSTATS_IFNAME, 3, "all");
for (i = 0; i < num; i++, array++) {
*array = fold_field((void **)ipv6_stats,
i * (sizeof(unsigned long)));
}
} else {
/* fill IP mibs interface statistics */
r->ipstats_ifindex = idev->dev->ifindex;
RTA_PUT(skb, IPSTATS_IFNAME, strlen(idev->dev->name)+1,
idev->dev->name);
for (i = 0; i < num; i++, array++) {
*array = fold_field((void **)idev->stats.ipv6,
i * (sizeof(unsigned long)));
}
}
RTA_PUT(skb, IPSTATS_COUNTERS, sizeof(struct ip_stats), &ipstats);
nlh->nlmsg_len = skb->tail - b;
return skb->len;
nlmsg_failure:
rtattr_failure:
skb_trim(skb, b - skb->data);
return -1;
}
static int inet6_dump_ipstats(struct sk_buff *skb, struct netlink_callback *cb)
{
int err, idx = 0;
int s_idx = cb->args[0];
struct net_device *dev;
struct inet6_dev *idev;
/* fill IP mibs system statistics */
inet6_fill_ipstats(skb, NULL, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWIPSTATS);
idx += 1;
/* fill IP mibs interface statistics */
read_lock(&dev_base_lock);
for (dev=dev_base; dev; dev = dev->next, idx++) {
if (idx < s_idx)
continue;
if ((idev = in6_dev_get(dev)) == NULL)
continue;
err = inet6_fill_ipstats(skb, idev, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, RTM_NEWIPSTATS);
in6_dev_put(idev);
if (err <= 0)
break;
}
read_unlock(&dev_base_lock);
cb->args[0] = idx;
return skb->len;
}
static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
[RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, },
[RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, },
......@@ -3069,7 +2974,6 @@ static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
[RTM_DELROUTE - RTM_BASE] = { .doit = inet6_rtm_delroute, },
[RTM_GETROUTE - RTM_BASE] = { .doit = inet6_rtm_getroute,
.dumpit = inet6_dump_fib, },
[RTM_GETIPSTATS - RTM_BASE] = { .dumpit = inet6_dump_ipstats, },
};
static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
......
......@@ -670,9 +670,6 @@ static int __init init_ipv6_mibs(void)
if (snmp6_mib_init((void **)ipv6_statistics, sizeof (struct ipv6_mib),
__alignof__(struct ipv6_mib)) < 0)
goto err_ip_mib;
if (snmp6_mib_init((void **)ipv6_stats, sizeof (struct ip_stats),
__alignof__(struct ip_stats)) < 0)
goto err_ip6_mib;
if (snmp6_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib),
__alignof__(struct ipv6_mib)) < 0)
goto err_icmp_mib;
......@@ -684,8 +681,6 @@ static int __init init_ipv6_mibs(void)
err_udp_mib:
snmp6_mib_free((void **)icmpv6_statistics);
err_icmp_mib:
snmp6_mib_free((void **)ipv6_stats);
err_ip6_mib:
snmp6_mib_free((void **)ipv6_statistics);
err_ip_mib:
return -ENOMEM;
......@@ -695,7 +690,6 @@ static int __init init_ipv6_mibs(void)
static void cleanup_ipv6_mibs(void)
{
snmp6_mib_free((void **)ipv6_statistics);
snmp6_mib_free((void **)ipv6_stats);
snmp6_mib_free((void **)icmpv6_statistics);
snmp6_mib_free((void **)udp_stats_in6);
}
......
......@@ -156,15 +156,10 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
{
struct sk_buff *skb = *skbp;
struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
struct inet6_dev *idev = NULL;
if (likely(skb->dev))
idev = __in6_dev_get(skb->dev);
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
kfree_skb(skb);
return -1;
}
......@@ -178,7 +173,6 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
}
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
return -1;
}
......@@ -230,15 +224,10 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
struct ipv6_rt_hdr *hdr;
struct rt0_hdr *rthdr;
struct inet6_dev *idev = NULL;
if (likely(skb->dev))
idev = __in6_dev_get(skb->dev);
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
kfree_skb(skb);
return -1;
}
......@@ -248,7 +237,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
skb->pkt_type != PACKET_HOST) {
IP6_INC_STATS_BH(Ip6InAddrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInAddrErrors);
kfree_skb(skb);
return -1;
}
......@@ -265,14 +253,12 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if (hdr->type != IPV6_SRCRT_TYPE_0) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
return -1;
}
if (hdr->hdrlen & 0x01) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
return -1;
}
......@@ -286,7 +272,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if (hdr->segments_left > n) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
return -1;
}
......@@ -300,7 +285,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
/* the copy is a forwarded packet */
if (skb2 == NULL) {
IP6_INC_STATS_BH(Ip6OutDiscards);
IPV6_INC_STATS_BH(idev, ipStatsOutDiscards);
return -1;
}
*skbp = skb = skb2;
......@@ -319,7 +303,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if (ipv6_addr_is_multicast(addr)) {
IP6_INC_STATS_BH(Ip6InAddrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInAddrErrors);
kfree_skb(skb);
return -1;
}
......@@ -337,7 +320,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if (skb->dst->dev->flags&IFF_LOOPBACK) {
if (skb->nh.ipv6h->hop_limit <= 1) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
0, skb->dev);
kfree_skb(skb);
......@@ -450,36 +432,28 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
{
u32 pkt_len;
struct inet6_dev *idev = NULL;
if (likely(skb->dev))
idev = __in6_dev_get(skb->dev);
if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
LIMIT_NETDEBUG(
printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]));
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
goto drop;
}
pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
if (pkt_len <= IPV6_MAXPLEN) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
return 0;
}
if (skb->nh.ipv6h->payload_len) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
return 0;
}
if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
IP6_INC_STATS_BH(Ip6InTruncatedPkts);
IPV6_INC_STATS_BH(idev, ipStatsInTruncatedPkts);
goto drop;
}
if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
......
......@@ -158,7 +158,6 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
{
struct dst_entry *dst;
int res = 0;
struct inet6_dev *idev = NULL;
/* Informational messages are not limited. */
if (type & ICMPV6_INFOMSG_MASK)
......@@ -174,12 +173,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
* this lookup should be more aggressive (not longer than timeout).
*/
dst = ip6_route_output(sk, fl);
/* idev reference for IP MIBs */
if (likely(dst->dev))
idev = in6_dev_get(dst->dev);
if (dst->error) {
IP6_INC_STATS(Ip6OutNoRoutes);
IPV6_INC_STATS(idev, ipStatsOutNoRoutes);
} else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
res = 1;
} else {
......@@ -192,9 +187,6 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
res = xrlim_allow(dst, tmo);
}
/* release the idev reference for IP MIBs */
if (likely(idev))
in6_dev_put(idev);
dst_release(dst);
return res;
}
......
......@@ -60,22 +60,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
{
struct ipv6hdr *hdr;
u32 pkt_len;
struct inet6_dev *idev = NULL;
int err = 0;
/* idev reference for input IP MIBs */
if (likely(skb->dev))
idev = in6_dev_get(skb->dev);
if (skb->pkt_type == PACKET_OTHERHOST)
goto drop;
IP6_INC_STATS_BH(Ip6InReceives);
IPV6_INC_STATS_BH(idev, ipStatsInReceives);
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
IP6_INC_STATS_BH(Ip6InDiscards);
IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
goto out;
}
......@@ -89,7 +81,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
goto drop;
}
......@@ -99,7 +90,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
goto err;
pkt_len = ntohs(hdr->payload_len);
IPV6_ADD_STATS_BH(idev, ipStatsInOctets, skb->len);
/* pkt_len may be zero if Jumbo payload option is present */
if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
......@@ -108,7 +98,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr))){
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
goto drop;
}
hdr = skb->nh.ipv6h;
......@@ -121,26 +110,20 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
skb->h.raw = (u8*)(hdr+1);
if (ipv6_parse_hopopts(skb, offsetof(struct ipv6hdr, nexthdr)) < 0) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
goto out;
return 0;
}
hdr = skb->nh.ipv6h;
}
err = NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
goto out;
return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
truncated:
IP6_INC_STATS_BH(Ip6InTruncatedPkts);
IPV6_INC_STATS_BH(idev, ipStatsInTruncatedPkts);
err:
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
drop:
kfree_skb(skb);
out:
if (likely(idev))
in6_dev_put(idev);
return err;
return 0;
}
/*
......@@ -156,10 +139,6 @@ static inline int ip6_input_finish(struct sk_buff *skb)
int nexthdr;
u8 hash;
int cksum_sub = 0;
struct inet6_dev *idev = NULL;
if (skb->dev)
idev = __in6_dev_get(skb->dev);
skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
......@@ -214,20 +193,16 @@ static inline int ip6_input_finish(struct sk_buff *skb)
ret = ipprot->handler(&skb, &nhoff);
if (ret > 0)
goto resubmit;
else if (ret == 0) {
else if (ret == 0)
IP6_INC_STATS_BH(Ip6InDelivers);
IPV6_INC_STATS_BH(idev, ipStatsInDelivers);
}
} else {
if (!raw_sk) {
if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
IP6_INC_STATS_BH(Ip6InUnknownProtos);
IPV6_INC_STATS_BH(idev, ipStatsInUnknownProtos);
icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff);
}
} else {
IP6_INC_STATS_BH(Ip6InDelivers);
IPV6_INC_STATS_BH(idev, ipStatsInDelivers);
kfree_skb(skb);
}
}
......@@ -236,7 +211,6 @@ static inline int ip6_input_finish(struct sk_buff *skb)
discard:
IP6_INC_STATS_BH(Ip6InDiscards);
IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
rcu_read_unlock();
kfree_skb(skb);
return 0;
......@@ -252,13 +226,8 @@ int ip6_mc_input(struct sk_buff *skb)
{
struct ipv6hdr *hdr;
int deliver;
struct inet6_dev *idev = NULL;
if (skb->dev)
idev = __in6_dev_get(skb->dev);
IP6_INC_STATS_BH(Ip6InMcastPkts);
IPV6_INC_STATS_BH(idev, ipStatsInMcastPkts);
IPV6_ADD_STATS_BH(idev, ipStatsInMcastOctets, skb->len);
hdr = skb->nh.ipv6h;
deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) ||
......
......@@ -74,10 +74,6 @@ static inline int ip6_output_finish(struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
struct hh_cache *hh = dst->hh;
struct inet6_dev *idev = NULL;
if (likely(skb->dev))
idev = __in6_dev_get(skb->dev);
if (hh) {
int hh_alen;
......@@ -87,15 +83,11 @@ static inline int ip6_output_finish(struct sk_buff *skb)
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len);
IPV6_INC_STATS_BH(idev, ipStatsOutTransmits);
return hh->hh_output(skb);
} else if (dst->neighbour) {
IPV6_INC_STATS_BH(idev, ipStatsOutTransmits);
} else if (dst->neighbour)
return dst->neighbour->output(skb);
}
IP6_INC_STATS_BH(Ip6OutNoRoutes);
IPV6_INC_STATS_BH(idev, ipStatsOutDiscards);
kfree_skb(skb);
return -EINVAL;
......@@ -119,12 +111,9 @@ int ip6_output2(struct sk_buff *skb)
{
struct dst_entry *dst = skb->dst;
struct net_device *dev = dst->dev;
struct inet6_dev *idev = NULL;
skb->protocol = htons(ETH_P_IPV6);
skb->dev = dev;
if (likely(dev))
idev = __in6_dev_get(dev);
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
......@@ -144,15 +133,12 @@ int ip6_output2(struct sk_buff *skb)
if (skb->nh.ipv6h->hop_limit == 0) {
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
kfree_skb(skb);
return 0;
}
}
IP6_INC_STATS(Ip6OutMcastPkts);
IPV6_INC_STATS(idev, ipStatsOutMcastPkts);
IPV6_ADD_STATS(idev, ipStatsOutMcastOctets, skb->len);
}
return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
......@@ -171,7 +157,6 @@ int ip6_route_me_harder(struct sk_buff *skb)
{
struct ipv6hdr *iph = skb->nh.ipv6h;
struct dst_entry *dst;
struct inet6_dev *idev = NULL;
struct flowi fl = {
.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
.nl_u =
......@@ -182,26 +167,18 @@ int ip6_route_me_harder(struct sk_buff *skb)
};
dst = ip6_route_output(skb->sk, &fl);
if (likely(skb->dev))
idev = __in6_dev_get(skb->dev);
if (dst->error) {
IP6_INC_STATS(Ip6OutNoRoutes);
IPV6_INC_STATS_BH(idev, ipStatsOutNoRoutes);
LIMIT_NETDEBUG(
printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n"));
dst_release(dst);
return -EINVAL;
}
/* drop the IP MIBs reference for old idev */
if (likely(skb->dst))
in6_dev_put(__in6_dev_get(skb->dst->dev));
/* Drop old route. */
dst_release(skb->dst);
/* IP MIBs refer to the new dst idev */
if (likely(dst->dev))
idev = in6_dev_get(dst->dev);
skb->dst = dst;
return 0;
}
......@@ -235,12 +212,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
int seg_len = skb->len;
int hlimit;
u32 mtu;
struct inet6_dev *idev = NULL;
int errno = 0;
/* idev reference for IP MIBs */
if (likely(skb->dst))
idev = in6_dev_get(skb->dst->dev);
if (opt) {
int head_room;
......@@ -258,9 +229,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
skb = skb2;
if (skb == NULL) {
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
errno = -ENOBUFS;
goto out;
return -ENOBUFS;
}
if (sk)
skb_set_owner_w(skb, sk);
......@@ -294,10 +263,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
mtu = dst_pmtu(dst);
if ((skb->len <= mtu) || ipfragok) {
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
errno = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
goto out;
return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
}
if (net_ratelimit())
......@@ -305,13 +271,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
IP6_INC_STATS(Ip6FragFails);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
kfree_skb(skb);
errno = -EMSGSIZE;
out:
if (likely(idev))
in6_dev_put(idev);
return errno;
return -EMSGSIZE;
}
/*
......@@ -386,22 +347,12 @@ int ip6_forward(struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
struct ipv6hdr *hdr = skb->nh.ipv6h;
struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
struct inet6_dev *idev = NULL;
int errno = 0;
/* idev reference for IP MIBs*/
if (likely(dst))
idev = in6_dev_get(dst->dev);
if (ipv6_devconf.forwarding == 0) {
errno = -EINVAL;
if (ipv6_devconf.forwarding == 0)
goto error;
}
if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
IP6_INC_STATS(Ip6InDiscards);
IPV6_INC_STATS(idev, ipStatsInDiscards);
errno = -EINVAL;
goto drop;
}
......@@ -423,7 +374,7 @@ int ip6_forward(struct sk_buff *skb)
if (opt->ra) {
u8 *ptr = skb->nh.raw + opt->ra;
if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
goto out;
return 0;
}
/*
......@@ -434,17 +385,13 @@ int ip6_forward(struct sk_buff *skb)
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
0, skb->dev);
IP6_INC_STATS(Ip6InDiscards);
IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
kfree_skb(skb);
errno = -ETIMEDOUT;
goto out;
return -ETIMEDOUT;
}
if (!xfrm6_route_forward(skb)) {
IP6_INC_STATS(Ip6InDiscards);
IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
errno = -EINVAL;
goto drop;
}
......@@ -475,7 +422,6 @@ int ip6_forward(struct sk_buff *skb)
} else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK
|IPV6_ADDR_LINKLOCAL)) {
/* This check is security critical. */
errno = -EINVAL;
goto error;
}
......@@ -485,16 +431,12 @@ int ip6_forward(struct sk_buff *skb)
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_pmtu(dst), skb->dev);
IP6_INC_STATS_BH(Ip6InTooBigErrors);
IP6_INC_STATS_BH(Ip6FragFails);
IPV6_INC_STATS_BH(idev, ipStatsOutFragFails);
kfree_skb(skb);
errno = -EMSGSIZE;
goto out;
return -EMSGSIZE;
}
if (skb_cow(skb, dst->dev->hard_header_len)) {
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
errno = -EINVAL;
goto drop;
}
......@@ -505,18 +447,13 @@ int ip6_forward(struct sk_buff *skb)
hdr->hop_limit--;
IP6_INC_STATS_BH(Ip6OutForwDatagrams);
IPV6_INC_STATS_BH(idev, ipStatsOutForwDatagrams);
errno = NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
goto out;
return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
error:
IP6_INC_STATS_BH(Ip6InAddrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInAddrErrors);
drop:
kfree_skb(skb);
out:
if (likely(idev))
in6_dev_put(idev);
return errno;
return -EINVAL;
}
static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
......@@ -587,11 +524,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
u32 frag_id = 0;
int ptr, offset = 0, err=0;
u8 *prevhdr, nexthdr = 0;
struct inet6_dev *idev = NULL;
dev = rt->u.dst.dev;
if (likely(dev))
idev = __in6_dev_get(dev);
hlen = ip6_find_1stfragopt(skb, &prevhdr);
nexthdr = *prevhdr;
......@@ -630,7 +564,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
tmp_hdr = kmalloc(hlen, GFP_ATOMIC);
if (!tmp_hdr) {
IP6_INC_STATS(Ip6FragFails);
IPV6_INC_STATS(idev, ipStatsOutFragFails);
return -ENOMEM;
}
......@@ -686,7 +619,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
if (err == 0) {
IP6_INC_STATS(Ip6FragOKs);
IPV6_INC_STATS(idev, ipStatsOutFragOKs);
return 0;
}
......@@ -697,7 +629,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
}
IP6_INC_STATS(Ip6FragFails);
IPV6_INC_STATS(idev, ipStatsOutFragFails);
return err;
}
......@@ -731,7 +662,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n"));
IP6_INC_STATS(Ip6FragFails);
IPV6_INC_STATS(idev, ipStatsOutFragFails);
err = -ENOMEM;
goto fail;
}
......@@ -790,7 +720,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
*/
IP6_INC_STATS(Ip6FragCreates);
IPV6_INC_STATS(idev, ipStatsOutFragCreates);
err = output(frag);
if (err)
......@@ -798,13 +727,11 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
}
kfree_skb(skb);
IP6_INC_STATS(Ip6FragOKs);
IPV6_INC_STATS(idev, ipStatsOutFragOKs);
return err;
fail:
kfree_skb(skb);
IP6_INC_STATS(Ip6FragFails);
IPV6_INC_STATS(idev, ipStatsOutFragFails);
return err;
}
......@@ -895,7 +822,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
int err;
int offset = 0;
int csummode = CHECKSUM_NONE;
struct inet6_dev *idev = NULL;
if (flags&MSG_PROBE)
return 0;
......@@ -1090,10 +1016,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
return 0;
error:
inet->cork.length -= length;
if (likely(skb->dev))
idev = __in6_dev_get(skb->dev);
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
return err;
}
......@@ -1110,7 +1033,6 @@ int ip6_push_pending_frames(struct sock *sk)
struct flowi *fl = &inet->cork.fl;
unsigned char proto = fl->proto;
int err = 0;
struct inet6_dev *idev = NULL;
if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
goto out;
......@@ -1154,12 +1076,7 @@ int ip6_push_pending_frames(struct sock *sk)
ipv6_addr_copy(&hdr->daddr, final_dst);
skb->dst = dst_clone(&rt->u.dst);
/* idev reference for IP MIBs */
if (likely(skb->dst))
idev = in6_dev_get(skb->dst->dev);
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
if (err) {
if (err > 0)
......@@ -1179,8 +1096,6 @@ int ip6_push_pending_frames(struct sock *sk)
np->cork.rt = NULL;
}
memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
if (likely(idev))
in6_dev_put(idev);
return err;
error:
goto out;
......@@ -1191,22 +1106,11 @@ void ip6_flush_pending_frames(struct sock *sk)
struct inet_opt *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff *skb;
struct inet6_dev *idev = NULL;
while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
if (skb->dst) {
if (!idev || skb->dst->dev != idev->dev) {
if (idev)
in6_dev_put(idev);
idev = in6_dev_get(skb->dst->dev);
}
}
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
kfree_skb(skb);
}
if (idev)
in6_dev_put(idev);
inet->cork.flags &= ~IPCORK_OPT;
......
......@@ -56,7 +56,6 @@
#include <asm/uaccess.h>
DEFINE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
DEFINE_SNMP_STAT(struct ip_stats, ipv6_stats);
static struct packet_type ipv6_packet_type = {
.type = __constant_htons(ETH_P_IPV6),
......
......@@ -1318,8 +1318,6 @@ static void mld_sendpack(struct sk_buff *skb)
int err;
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
sizeof(struct ipv6hdr);
mldlen = skb->tail - skb->h.raw;
......@@ -1332,13 +1330,10 @@ static void mld_sendpack(struct sk_buff *skb)
if (!err) {
ICMP6_INC_STATS(idev,Icmp6OutMsgs);
IP6_INC_STATS(Ip6OutMcastPkts);
IPV6_INC_STATS(idev, ipStatsOutMcastPkts);
IPV6_ADD_STATS(idev, ipStatsOutMcastOctets, skb->len);
} else {
} else
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
}
if (idev)
if (likely(idev != NULL))
in6_dev_put(idev);
}
......@@ -1618,9 +1613,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
idev = in6_dev_get(dev);
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
snd_addr = addr;
if (type == ICMPV6_MGM_REDUCTION) {
snd_addr = &all_routers;
......@@ -1635,13 +1628,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
if (skb == NULL) {
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
if (idev)
in6_dev_put(idev);
return;
}
IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
skb_reserve(skb, LL_RESERVED_SPACE(dev));
if (dev->hard_header) {
unsigned char ha[MAX_ADDR_LEN];
......@@ -1673,6 +1662,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPPROTO_ICMPV6,
csum_partial((__u8 *) hdr, len, 0));
idev = in6_dev_get(skb->dev);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit);
if (!err) {
......@@ -1682,22 +1673,16 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
ICMP6_INC_STATS(idev, Icmp6OutMsgs);
IP6_INC_STATS(Ip6OutMcastPkts);
IPV6_INC_STATS(idev, ipStatsOutMcastPkts);
IPV6_ADD_STATS(idev, ipStatsOutMcastOctets, skb->len);
} else {
} else
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
}
if (likely(idev != NULL))
in6_dev_put(idev);
return;
out:
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
kfree_skb(skb);
if (likely(idev != NULL))
in6_dev_put(idev);
}
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
......
......@@ -453,7 +453,6 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements);
......@@ -538,7 +537,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits);
......@@ -612,7 +610,6 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits);
......@@ -1339,7 +1336,6 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
buff->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutRedirects);
......
......@@ -227,9 +227,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
__alignof__(struct icmpv6_mib)) < 0)
goto err_icmp;
if (snmp6_mib_init((void **)idev->stats.ipv6, sizeof(struct ip_stats),
__alignof__(struct ip_stats)) < 0)
goto err_ip;
if (!proc_net_devsnmp6) {
err = -ENOENT;
......@@ -245,11 +242,8 @@ int snmp6_register_dev(struct inet6_dev *idev)
return 0;
err_proc:
snmp6_mib_free((void **)idev->stats.ipv6);
err_ip:
snmp6_mib_free((void **)idev->stats.icmpv6);
err_icmp:
return err;
}
......@@ -262,7 +256,6 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
remove_proc_entry(idev->stats.proc_dir_entry->name,
proc_net_devsnmp6);
snmp6_mib_free((void **)idev->stats.icmpv6);
snmp6_mib_free((void **)idev->stats.ipv6);
return 0;
}
......@@ -312,13 +305,9 @@ int snmp6_register_dev(struct inet6_dev *idev)
if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
__alignof__(struct icmpv6_mib)) < 0)
goto err_icmp;
if (snmp6_mib_init((void **)idev->stats.ipv6, sizeof(struct ip_stats),
__alignof__(struct ip_stats)) < 0)
goto err_ip;
return 0;
err_ip:
snmp6_mib_free((void **)idev->stats.icmpv6);
err_icmp:
return err;
}
......@@ -326,7 +315,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
int snmp6_unregister_dev(struct inet6_dev *idev)
{
snmp6_mib_free((void **)idev->stats.icmpv6);
snmp6_mib_free((void **)idev->stats.ipv6);
return 0;
}
......
......@@ -506,15 +506,11 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
struct ipv6hdr *iph;
struct sk_buff *skb;
unsigned int hh_len;
int err = 0;
struct inet6_dev *idev = NULL;
/* hold reference for IP MIBs */
int err;
if (length > rt->u.dst.dev->mtu) {
ipv6_local_error(sk, EMSGSIZE, fl, rt->u.dst.dev->mtu);
err = -EMSGSIZE;
goto out;
return -EMSGSIZE;
}
if (flags&MSG_PROBE)
goto out;
......@@ -530,9 +526,6 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
skb->priority = sk->sk_priority;
skb->dst = dst_clone(&rt->u.dst);
if (skb->dst)
idev = in6_dev_get(skb->dst->dev);
skb->nh.ipv6h = iph = (struct ipv6hdr *)skb_put(skb, length);
skb->ip_summed = CHECKSUM_NONE;
......@@ -543,26 +536,20 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
goto error_fault;
IP6_INC_STATS(Ip6OutRequests);
IPV6_INC_STATS(idev, ipStatsOutRequests);
IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
dst_output);
if (err > 0)
err = inet->recverr ? net_xmit_errno(err) : 0;
if (err)
goto error;
else
goto out;
out:
return 0;
error_fault:
err = -EFAULT;
kfree_skb(skb);
error:
IP6_INC_STATS(Ip6OutDiscards);
IPV6_INC_STATS(idev, ipStatsOutDiscards);
out:
if (idev)
in6_dev_put(idev);
return err;
}
static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
......
......@@ -264,7 +264,6 @@ static void ip6_evictor(void)
{
struct frag_queue *fq;
struct list_head *tmp;
struct inet6_dev *idev = NULL;
for(;;) {
if (atomic_read(&ip6_frag_mem) <= sysctl_ip6frag_low_thresh)
......@@ -286,18 +285,12 @@ static void ip6_evictor(void)
fq_put(fq);
IP6_INC_STATS_BH(Ip6ReasmFails);
/* idev might be pointed to NULL */
if (fq->fragments)
idev = __in6_dev_get(fq->fragments->dev);
IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
}
}
static void ip6_frag_expire(unsigned long data)
{
struct frag_queue *fq = (struct frag_queue *) data;
struct net_device *dev;
struct inet6_dev *idev = NULL;
spin_lock(&fq->lock);
......@@ -308,14 +301,10 @@ static void ip6_frag_expire(unsigned long data)
IP6_INC_STATS_BH(Ip6ReasmTimeout);
IP6_INC_STATS_BH(Ip6ReasmFails);
dev = dev_get_by_index(fq->iif);
if (dev)
idev = __in6_dev_get(dev);
IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
/* Send error only if the first segment arrived. */
if (fq->last_in&FIRST_IN && fq->fragments) {
struct net_device *dev = dev_get_by_index(fq->iif);
/*
But use as source device on which LAST ARRIVED
......@@ -326,10 +315,9 @@ static void ip6_frag_expire(unsigned long data)
fq->fragments->dev = dev;
icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0,
dev);
dev_put(dev);
}
}
if (dev)
dev_put(dev);
out:
spin_unlock(&fq->lock);
fq_put(fq);
......@@ -379,7 +367,6 @@ static struct frag_queue *
ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst)
{
struct frag_queue *fq;
struct inet6_dev *idev = NULL;
if ((fq = frag_alloc_queue()) == NULL)
goto oom;
......@@ -400,7 +387,6 @@ ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr
oom:
IP6_INC_STATS_BH(Ip6ReasmFails);
IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
return NULL;
}
......@@ -431,10 +417,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
{
struct sk_buff *prev, *next;
int offset, end;
struct inet6_dev *idev = NULL;
if (skb->dev)
idev = __in6_dev_get(skb->dev);
if (fq->last_in & COMPLETE)
goto err;
......@@ -444,7 +427,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
if ((unsigned int)end > IPV6_MAXPLEN) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
return;
}
......@@ -472,7 +454,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
* this case. -DaveM
*/
IP6_INC_STATS_BH(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
offsetof(struct ipv6hdr, payload_len));
return;
......@@ -592,7 +573,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
err:
IP6_INC_STATS(Ip6ReasmFails);
IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
kfree_skb(skb);
}
......@@ -612,10 +592,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
struct sk_buff *fp, *head = fq->fragments;
int payload_len;
unsigned int nhoff;
struct inet6_dev *idev = NULL;
if (dev)
idev = __in6_dev_get(dev);
fq_kill(fq);
BUG_TRAP(head != NULL);
......@@ -690,7 +667,6 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
IP6_INC_STATS_BH(Ip6ReasmOKs);
IPV6_INC_STATS_BH(idev, ipStatsReasmOKs);
fq->fragments = NULL;
*nhoffp = nhoff;
return 1;
......@@ -704,7 +680,6 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
out_fail:
IP6_INC_STATS_BH(Ip6ReasmFails);
IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
return -1;
}
......@@ -715,25 +690,19 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
struct frag_hdr *fhdr;
struct frag_queue *fq;
struct ipv6hdr *hdr;
struct inet6_dev *idev = NULL;
if (dev)
idev = __in6_dev_get(dev);
hdr = skb->nh.ipv6h;
IP6_INC_STATS_BH(Ip6ReasmReqds);
IPV6_INC_STATS_BH(idev, ipStatsReasmReqds);
/* Jumbo payload inhibits frag. header */
if (hdr->payload_len==0) {
IP6_INC_STATS(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
return -1;
}
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
IP6_INC_STATS(Ip6InHdrErrors);
IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
return -1;
}
......@@ -745,7 +714,6 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
/* It is not a fragmented frame */
skb->h.raw += sizeof(struct frag_hdr);
IP6_INC_STATS_BH(Ip6ReasmOKs);
IPV6_INC_STATS_BH(idev, ipStatsReasmOKs);
*nhoffp = (u8*)fhdr - skb->nh.raw;
return 1;
......@@ -771,7 +739,6 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
}
IP6_INC_STATS_BH(Ip6ReasmFails);
IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
kfree_skb(skb);
return -1;
}
......
......@@ -85,8 +85,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static struct dst_entry *ip6_negative_advice(struct dst_entry *);
static int ip6_dst_gc(void);
static int ip6_pkt_indiscard(struct sk_buff *skb);
static int ip6_pkt_outdiscard(struct sk_buff *skb);
static int ip6_pkt_discard(struct sk_buff *skb);
static void ip6_link_failure(struct sk_buff *skb);
static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
......@@ -111,8 +110,8 @@ struct rt6_info ip6_null_entry = {
.obsolete = -1,
.error = -ENETUNREACH,
.metrics = { [RTAX_HOPLIMIT - 1] = 255, },
.input = ip6_pkt_indiscard,
.output = ip6_pkt_outdiscard,
.input = ip6_pkt_discard,
.output = ip6_pkt_discard,
.ops = &ip6_dst_ops,
.path = (struct dst_entry*)&ip6_null_entry,
}
......@@ -770,8 +769,8 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
dev_put(dev);
dev = &loopback_dev;
dev_hold(dev);
rt->u.dst.output = ip6_pkt_outdiscard;
rt->u.dst.input = ip6_pkt_indiscard;
rt->u.dst.output = ip6_pkt_discard;
rt->u.dst.input = ip6_pkt_discard;
rt->u.dst.error = -ENETUNREACH;
rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
goto install_route;
......@@ -1258,30 +1257,9 @@ int ipv6_route_ioctl(unsigned int cmd, void *arg)
* Drop the packet on the floor
*/
static int ip6_pkt_indiscard(struct sk_buff *skb)
int ip6_pkt_discard(struct sk_buff *skb)
{
struct inet6_dev *idev = NULL;
if (skb->dev)
idev = __in6_dev_get(skb->dev);
IP6_INC_STATS(Ip6InNoRoutes);
IPV6_INC_STATS(idev, ipStatsInNoRoutes);
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
kfree_skb(skb);
return 0;
}
static int ip6_pkt_outdiscard(struct sk_buff *skb)
{
struct inet6_dev *idev = NULL;
if (skb->dev)
idev = __in6_dev_get(skb->dev);
IP6_INC_STATS(Ip6OutNoRoutes);
IPV6_INC_STATS(idev, ipStatsOutNoRoutes);
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
kfree_skb(skb);
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment