Commit bdb7cc64 authored by Stephen Suryaputra's avatar Stephen Suryaputra Committed by David S. Miller

ipv6: Count interface receive statistics on the ingress netdev

The statistics such as InHdrErrors should be counted on the ingress
netdev rather than on the dev from the dst, which is the egress.
Signed-off-by: default avatarStephen Suryaputra <ssuryaextr@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 032234d8
...@@ -307,6 +307,20 @@ static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev) ...@@ -307,6 +307,20 @@ static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
return rcu_dereference_rtnl(dev->ip6_ptr); return rcu_dereference_rtnl(dev->ip6_ptr);
} }
/**
* __in6_dev_get_safely - get inet6_dev pointer from netdevice
* @dev: network device
*
* This is a safer version of __in6_dev_get
*/
static inline struct inet6_dev *__in6_dev_get_safely(const struct net_device *dev)
{
if (likely(dev))
return rcu_dereference_rtnl(dev->ip6_ptr);
else
return NULL;
}
/** /**
* in6_dev_get - get inet6_dev pointer from netdevice * in6_dev_get - get inet6_dev pointer from netdevice
* @dev: network device * @dev: network device
......
...@@ -280,6 +280,7 @@ static const struct tlvtype_proc tlvprocdestopt_lst[] = { ...@@ -280,6 +280,7 @@ static const struct tlvtype_proc tlvprocdestopt_lst[] = {
static int ipv6_destopt_rcv(struct sk_buff *skb) static int ipv6_destopt_rcv(struct sk_buff *skb)
{ {
struct inet6_dev *idev = __in6_dev_get(skb->dev);
struct inet6_skb_parm *opt = IP6CB(skb); struct inet6_skb_parm *opt = IP6CB(skb);
#if IS_ENABLED(CONFIG_IPV6_MIP6) #if IS_ENABLED(CONFIG_IPV6_MIP6)
__u16 dstbuf; __u16 dstbuf;
...@@ -291,7 +292,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) ...@@ -291,7 +292,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
!pskb_may_pull(skb, (skb_transport_offset(skb) + !pskb_may_pull(skb, (skb_transport_offset(skb) +
((skb_transport_header(skb)[1] + 1) << 3)))) { ((skb_transport_header(skb)[1] + 1) << 3)))) {
__IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), __IP6_INC_STATS(dev_net(dst->dev), idev,
IPSTATS_MIB_INHDRERRORS); IPSTATS_MIB_INHDRERRORS);
fail_and_free: fail_and_free:
kfree_skb(skb); kfree_skb(skb);
...@@ -319,8 +320,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) ...@@ -319,8 +320,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
return 1; return 1;
} }
__IP6_INC_STATS(dev_net(dst->dev), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
return -1; return -1;
} }
...@@ -416,8 +416,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb) ...@@ -416,8 +416,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
} }
if (hdr->segments_left >= (hdr->hdrlen >> 1)) { if (hdr->segments_left >= (hdr->hdrlen >> 1)) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
((&hdr->segments_left) - ((&hdr->segments_left) -
skb_network_header(skb))); skb_network_header(skb)));
...@@ -456,8 +455,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb) ...@@ -456,8 +455,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
if (skb_dst(skb)->dev->flags & IFF_LOOPBACK) { if (skb_dst(skb)->dev->flags & IFF_LOOPBACK) {
if (ipv6_hdr(skb)->hop_limit <= 1) { if (ipv6_hdr(skb)->hop_limit <= 1) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
icmpv6_send(skb, ICMPV6_TIME_EXCEED, icmpv6_send(skb, ICMPV6_TIME_EXCEED,
ICMPV6_EXC_HOPLIMIT, 0); ICMPV6_EXC_HOPLIMIT, 0);
kfree_skb(skb); kfree_skb(skb);
...@@ -481,10 +479,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb) ...@@ -481,10 +479,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
/* called with rcu_read_lock() */ /* called with rcu_read_lock() */
static int ipv6_rthdr_rcv(struct sk_buff *skb) static int ipv6_rthdr_rcv(struct sk_buff *skb)
{ {
struct inet6_dev *idev = __in6_dev_get(skb->dev);
struct inet6_skb_parm *opt = IP6CB(skb); struct inet6_skb_parm *opt = IP6CB(skb);
struct in6_addr *addr = NULL; struct in6_addr *addr = NULL;
struct in6_addr daddr; struct in6_addr daddr;
struct inet6_dev *idev;
int n, i; int n, i;
struct ipv6_rt_hdr *hdr; struct ipv6_rt_hdr *hdr;
struct rt0_hdr *rthdr; struct rt0_hdr *rthdr;
...@@ -498,8 +496,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -498,8 +496,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
!pskb_may_pull(skb, (skb_transport_offset(skb) + !pskb_may_pull(skb, (skb_transport_offset(skb) +
((skb_transport_header(skb)[1] + 1) << 3)))) { ((skb_transport_header(skb)[1] + 1) << 3)))) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
...@@ -508,8 +505,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -508,8 +505,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
skb->pkt_type != PACKET_HOST) { skb->pkt_type != PACKET_HOST) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
IPSTATS_MIB_INADDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
...@@ -527,7 +523,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -527,7 +523,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
* processed by own * processed by own
*/ */
if (!addr) { if (!addr) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev,
IPSTATS_MIB_INADDRERRORS); IPSTATS_MIB_INADDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
...@@ -553,8 +549,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -553,8 +549,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
goto unknown_rh; goto unknown_rh;
/* Silently discard invalid RTH type 2 */ /* Silently discard invalid RTH type 2 */
if (hdr->hdrlen != 2 || hdr->segments_left != 1) { if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
...@@ -572,8 +567,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -572,8 +567,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
n = hdr->hdrlen >> 1; n = hdr->hdrlen >> 1;
if (hdr->segments_left > n) { if (hdr->segments_left > n) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
((&hdr->segments_left) - ((&hdr->segments_left) -
skb_network_header(skb))); skb_network_header(skb)));
...@@ -609,14 +603,12 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -609,14 +603,12 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
(xfrm_address_t *)&ipv6_hdr(skb)->saddr, (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
IPPROTO_ROUTING) < 0) { IPPROTO_ROUTING) < 0) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
IPSTATS_MIB_INADDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
if (!ipv6_chk_home_addr(dev_net(skb_dst(skb)->dev), addr)) { if (!ipv6_chk_home_addr(dev_net(skb_dst(skb)->dev), addr)) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
IPSTATS_MIB_INADDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
...@@ -627,8 +619,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -627,8 +619,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
} }
if (ipv6_addr_is_multicast(addr)) { if (ipv6_addr_is_multicast(addr)) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
IPSTATS_MIB_INADDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
...@@ -647,8 +638,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -647,8 +638,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
if (skb_dst(skb)->dev->flags&IFF_LOOPBACK) { if (skb_dst(skb)->dev->flags&IFF_LOOPBACK) {
if (ipv6_hdr(skb)->hop_limit <= 1) { if (ipv6_hdr(skb)->hop_limit <= 1) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
0); 0);
kfree_skb(skb); kfree_skb(skb);
...@@ -663,7 +653,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ...@@ -663,7 +653,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
return -1; return -1;
unknown_rh: unknown_rh:
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS); __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
(&hdr->type) - skb_network_header(skb)); (&hdr->type) - skb_network_header(skb));
return -1; return -1;
...@@ -755,34 +745,31 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff) ...@@ -755,34 +745,31 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
{ {
const unsigned char *nh = skb_network_header(skb); const unsigned char *nh = skb_network_header(skb);
struct inet6_dev *idev = __in6_dev_get_safely(skb->dev);
struct net *net = ipv6_skb_net(skb); struct net *net = ipv6_skb_net(skb);
u32 pkt_len; u32 pkt_len;
if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
nh[optoff+1]); nh[optoff+1]);
__IP6_INC_STATS(net, ipv6_skb_idev(skb), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
goto drop; goto drop;
} }
pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
if (pkt_len <= IPV6_MAXPLEN) { if (pkt_len <= IPV6_MAXPLEN) {
__IP6_INC_STATS(net, ipv6_skb_idev(skb), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
return false; return false;
} }
if (ipv6_hdr(skb)->payload_len) { if (ipv6_hdr(skb)->payload_len) {
__IP6_INC_STATS(net, ipv6_skb_idev(skb), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
return false; return false;
} }
if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
__IP6_INC_STATS(net, ipv6_skb_idev(skb), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INTRUNCATEDPKTS);
IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop; goto drop;
} }
......
...@@ -336,7 +336,7 @@ int ip6_mc_input(struct sk_buff *skb) ...@@ -336,7 +336,7 @@ int ip6_mc_input(struct sk_buff *skb)
bool deliver; bool deliver;
__IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev), __IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev),
ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INMCAST, __in6_dev_get_safely(skb->dev), IPSTATS_MIB_INMCAST,
skb->len); skb->len);
hdr = ipv6_hdr(skb); hdr = ipv6_hdr(skb);
......
...@@ -425,6 +425,7 @@ static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) ...@@ -425,6 +425,7 @@ static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
int ip6_forward(struct sk_buff *skb) int ip6_forward(struct sk_buff *skb)
{ {
struct inet6_dev *idev = __in6_dev_get_safely(skb->dev);
struct dst_entry *dst = skb_dst(skb); struct dst_entry *dst = skb_dst(skb);
struct ipv6hdr *hdr = ipv6_hdr(skb); struct ipv6hdr *hdr = ipv6_hdr(skb);
struct inet6_skb_parm *opt = IP6CB(skb); struct inet6_skb_parm *opt = IP6CB(skb);
...@@ -444,8 +445,7 @@ int ip6_forward(struct sk_buff *skb) ...@@ -444,8 +445,7 @@ int ip6_forward(struct sk_buff *skb)
goto drop; goto drop;
if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
__IP6_INC_STATS(net, ip6_dst_idev(dst), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
IPSTATS_MIB_INDISCARDS);
goto drop; goto drop;
} }
...@@ -476,8 +476,7 @@ int ip6_forward(struct sk_buff *skb) ...@@ -476,8 +476,7 @@ int ip6_forward(struct sk_buff *skb)
/* Force OUTPUT device used as source address */ /* Force OUTPUT device used as source address */
skb->dev = dst->dev; skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0); icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
__IP6_INC_STATS(net, ip6_dst_idev(dst), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
kfree_skb(skb); kfree_skb(skb);
return -ETIMEDOUT; return -ETIMEDOUT;
...@@ -490,15 +489,13 @@ int ip6_forward(struct sk_buff *skb) ...@@ -490,15 +489,13 @@ int ip6_forward(struct sk_buff *skb)
if (proxied > 0) if (proxied > 0)
return ip6_input(skb); return ip6_input(skb);
else if (proxied < 0) { else if (proxied < 0) {
__IP6_INC_STATS(net, ip6_dst_idev(dst), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
IPSTATS_MIB_INDISCARDS);
goto drop; goto drop;
} }
} }
if (!xfrm6_route_forward(skb)) { if (!xfrm6_route_forward(skb)) {
__IP6_INC_STATS(net, ip6_dst_idev(dst), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
IPSTATS_MIB_INDISCARDS);
goto drop; goto drop;
} }
dst = skb_dst(skb); dst = skb_dst(skb);
...@@ -554,8 +551,7 @@ int ip6_forward(struct sk_buff *skb) ...@@ -554,8 +551,7 @@ int ip6_forward(struct sk_buff *skb)
/* Again, force OUTPUT device used as source address */ /* Again, force OUTPUT device used as source address */
skb->dev = dst->dev; skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
__IP6_INC_STATS(net, ip6_dst_idev(dst), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INTOOBIGERRORS);
IPSTATS_MIB_INTOOBIGERRORS);
__IP6_INC_STATS(net, ip6_dst_idev(dst), __IP6_INC_STATS(net, ip6_dst_idev(dst),
IPSTATS_MIB_FRAGFAILS); IPSTATS_MIB_FRAGFAILS);
kfree_skb(skb); kfree_skb(skb);
...@@ -579,7 +575,7 @@ int ip6_forward(struct sk_buff *skb) ...@@ -579,7 +575,7 @@ int ip6_forward(struct sk_buff *skb)
ip6_forward_finish); ip6_forward_finish);
error: error:
__IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS); __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
drop: drop:
kfree_skb(skb); kfree_skb(skb);
return -EINVAL; return -EINVAL;
......
...@@ -179,7 +179,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, ...@@ -179,7 +179,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
if ((unsigned int)end > IPV6_MAXPLEN) { if ((unsigned int)end > IPV6_MAXPLEN) {
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, __in6_dev_get_safely(skb->dev),
IPSTATS_MIB_INHDRERRORS); IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
((u8 *)&fhdr->frag_off - ((u8 *)&fhdr->frag_off -
...@@ -214,7 +214,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, ...@@ -214,7 +214,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
/* RFC2460 says always send parameter problem in /* RFC2460 says always send parameter problem in
* this case. -DaveM * this case. -DaveM
*/ */
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, __in6_dev_get_safely(skb->dev),
IPSTATS_MIB_INHDRERRORS); IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
offsetof(struct ipv6hdr, payload_len)); offsetof(struct ipv6hdr, payload_len));
...@@ -536,7 +536,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) ...@@ -536,7 +536,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
return -1; return -1;
fail_hdr: fail_hdr:
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, __in6_dev_get_safely(skb->dev),
IPSTATS_MIB_INHDRERRORS); IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb_network_header_len(skb)); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb_network_header_len(skb));
return -1; return -1;
......
...@@ -3541,7 +3541,8 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) ...@@ -3541,7 +3541,8 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
case IPSTATS_MIB_INNOROUTES: case IPSTATS_MIB_INNOROUTES:
type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
if (type == IPV6_ADDR_ANY) { if (type == IPV6_ADDR_ANY) {
IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), IP6_INC_STATS(dev_net(dst->dev),
__in6_dev_get_safely(skb->dev),
IPSTATS_MIB_INADDRERRORS); IPSTATS_MIB_INADDRERRORS);
break; break;
} }
......
...@@ -266,12 +266,13 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs, ...@@ -266,12 +266,13 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
/* check and decrement ttl */ /* check and decrement ttl */
if (ipv6_hdr(skb)->hop_limit <= 1) { if (ipv6_hdr(skb)->hop_limit <= 1) {
struct inet6_dev *idev = __in6_dev_get_safely(skb->dev);
/* Force OUTPUT device used as source address */ /* Force OUTPUT device used as source address */
skb->dev = dst->dev; skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_TIME_EXCEED, icmpv6_send(skb, ICMPV6_TIME_EXCEED,
ICMPV6_EXC_HOPLIMIT, 0); ICMPV6_EXC_HOPLIMIT, 0);
__IP6_INC_STATS(net, ip6_dst_idev(dst), __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
IPSTATS_MIB_INHDRERRORS);
return false; return false;
} }
......
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