Loading net/ipv6/xfrm6_input.c +3 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, sp = secpath_dup(skb->sp); if (!sp) { XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); goto drop; } if (skb->sp) Loading @@ -80,6 +81,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, } if (1 + skb->sp->len == XFRM_MAX_DEPTH) { XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); goto drop; } Loading Loading @@ -149,6 +151,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, } if (!x) { XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); goto drop; } Loading net/xfrm/xfrm_input.c +31 −10 Original line number Diff line number Diff line Loading @@ -119,8 +119,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) struct sec_path *sp; sp = secpath_dup(skb->sp); if (!sp) if (!sp) { XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); goto drop; } if (skb->sp) secpath_put(skb->sp); skb->sp = sp; Loading @@ -131,31 +133,45 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) family = XFRM_SPI_SKB_CB(skb)->family; seq = 0; if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) { XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); goto drop; } do { if (skb->sp->len == XFRM_MAX_DEPTH) if (skb->sp->len == XFRM_MAX_DEPTH) { XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); goto drop; } x = xfrm_state_lookup(daddr, spi, nexthdr, family); if (x == NULL) if (x == NULL) { XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); goto drop; } skb->sp->xvec[skb->sp->len++] = x; spin_lock(&x->lock); if (unlikely(x->km.state != XFRM_STATE_VALID)) if (unlikely(x->km.state != XFRM_STATE_VALID)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); goto drop_unlock; } if ((x->encap ? x->encap->encap_type : 0) != encap_type) if ((x->encap ? x->encap->encap_type : 0) != encap_type) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); goto drop_unlock; } if (x->props.replay_window && xfrm_replay_check(x, seq)) if (x->props.replay_window && xfrm_replay_check(x, seq)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW); goto drop_unlock; } if (xfrm_state_check_expire(x)) if (xfrm_state_check_expire(x)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED); goto drop_unlock; } spin_unlock(&x->lock); Loading @@ -171,6 +187,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) if (nexthdr <= 0) { if (nexthdr == -EBADMSG) x->stats.integrity_failed++; XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR); goto drop_unlock; } Loading @@ -187,8 +204,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; if (x->inner_mode->input(x, skb)) if (x->inner_mode->input(x, skb)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR); goto drop; } if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { decaps = 1; Loading @@ -203,8 +222,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) family = x->outer_mode->afinfo->family; err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); if (err < 0) if (err < 0) { XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); goto drop; } } while (!err); nf_reset(skb); Loading net/xfrm/xfrm_output.c +5 −1 Original line number Diff line number Diff line Loading @@ -69,10 +69,13 @@ static int xfrm_output_one(struct sk_buff *skb, int err) err = x->type->output(x, skb); resume: if (err) if (err) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR); goto error_nolock; } if (!(skb->dst = dst_pop(dst))) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); err = -EHOSTUNREACH; goto error_nolock; } Loading Loading @@ -167,6 +170,7 @@ int xfrm_output(struct sk_buff *skb) if (skb->ip_summed == CHECKSUM_PARTIAL) { err = skb_checksum_help(skb); if (err) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); kfree_skb(skb); return err; } Loading net/xfrm/xfrm_policy.c +51 −12 Original line number Diff line number Diff line Loading @@ -1494,9 +1494,11 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); err = PTR_ERR(policy); if (IS_ERR(policy)) if (IS_ERR(policy)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); goto dropdst; } } if (!policy) { /* To accelerate a bit... */ Loading Loading @@ -1529,6 +1531,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, default: case XFRM_POLICY_BLOCK: /* Prohibit the flow */ XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); err = -EPERM; goto error; Loading @@ -1548,6 +1551,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, */ dst = xfrm_find_bundle(fl, policy, family); if (IS_ERR(dst)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); err = PTR_ERR(dst); goto error; } Loading @@ -1562,10 +1566,12 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, XFRM_POLICY_OUT); if (pols[1]) { if (IS_ERR(pols[1])) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); err = PTR_ERR(pols[1]); goto error; } if (pols[1]->action == XFRM_POLICY_BLOCK) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); err = -EPERM; goto error; } Loading Loading @@ -1611,6 +1617,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family); if (nx == -EAGAIN && signal_pending(current)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); err = -ERESTART; goto error; } Loading @@ -1621,9 +1628,11 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, } err = nx; } if (err < 0) if (err < 0) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); goto error; } } if (nx == 0) { /* Flow passes not transformed. */ xfrm_pols_put(pols, npols); Loading @@ -1632,8 +1641,10 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig); err = PTR_ERR(dst); if (IS_ERR(dst)) if (IS_ERR(dst)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR); goto error; } for (pi = 0; pi < npols; pi++) { read_lock_bh(&pols[pi]->lock); Loading @@ -1652,6 +1663,10 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, if (dst) dst_free(dst); if (pol_dead) XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD); else XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); err = -EHOSTUNREACH; goto error; } Loading @@ -1664,6 +1679,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, write_unlock_bh(&policy->lock); if (dst) dst_free(dst); XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); goto error; } Loading Loading @@ -1817,8 +1833,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, dir &= XFRM_POLICY_MASK; fl_dir = policy_to_flow_dir(dir); if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) { XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); return 0; } nf_nat_decode_session(skb, &fl, family); /* First, check used SA against their selectors. */ Loading @@ -1827,28 +1846,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, for (i=skb->sp->len-1; i>=0; i--) { struct xfrm_state *x = skb->sp->xvec[i]; if (!xfrm_selector_match(&x->sel, &fl, family)) if (!xfrm_selector_match(&x->sel, &fl, family)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH); return 0; } } } pol = NULL; if (sk && sk->sk_policy[dir]) { pol = xfrm_sk_policy_lookup(sk, dir, &fl); if (IS_ERR(pol)) if (IS_ERR(pol)) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); return 0; } } if (!pol) pol = flow_cache_lookup(&fl, family, fl_dir, xfrm_policy_lookup); if (IS_ERR(pol)) if (IS_ERR(pol)) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); return 0; } if (!pol) { if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { xfrm_secpath_reject(xerr_idx, skb, &fl); XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS); return 0; } return 1; Loading @@ -1864,8 +1890,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, &fl, family, XFRM_POLICY_IN); if (pols[1]) { if (IS_ERR(pols[1])) if (IS_ERR(pols[1])) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); return 0; } pols[1]->curlft.use_time = get_seconds(); npols ++; } Loading @@ -1886,10 +1914,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, for (pi = 0; pi < npols; pi++) { if (pols[pi] != pol && pols[pi]->action != XFRM_POLICY_ALLOW) pols[pi]->action != XFRM_POLICY_ALLOW) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); goto reject; if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) } if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) { XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); goto reject_error; } for (i = 0; i < pols[pi]->xfrm_nr; i++) tpp[ti++] = &pols[pi]->xfrm_vec[i]; } Loading @@ -1911,16 +1943,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, if (k < -1) /* "-2 - errored_index" returned */ xerr_idx = -(2+k); XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); goto reject; } } if (secpath_has_nontransport(sp, k, &xerr_idx)) if (secpath_has_nontransport(sp, k, &xerr_idx)) { XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); goto reject; } xfrm_pols_put(pols, npols); return 1; } XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); reject: xfrm_secpath_reject(xerr_idx, skb, &fl); Loading @@ -1934,8 +1970,11 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) { struct flowi fl; if (xfrm_decode_session(skb, &fl, family) < 0) if (xfrm_decode_session(skb, &fl, family) < 0) { /* XXX: we should have something like FWDHDRERROR here. */ XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); return 0; } return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0; } Loading Loading
net/ipv6/xfrm6_input.c +3 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, sp = secpath_dup(skb->sp); if (!sp) { XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); goto drop; } if (skb->sp) Loading @@ -80,6 +81,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, } if (1 + skb->sp->len == XFRM_MAX_DEPTH) { XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); goto drop; } Loading Loading @@ -149,6 +151,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, } if (!x) { XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); goto drop; } Loading
net/xfrm/xfrm_input.c +31 −10 Original line number Diff line number Diff line Loading @@ -119,8 +119,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) struct sec_path *sp; sp = secpath_dup(skb->sp); if (!sp) if (!sp) { XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); goto drop; } if (skb->sp) secpath_put(skb->sp); skb->sp = sp; Loading @@ -131,31 +133,45 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) family = XFRM_SPI_SKB_CB(skb)->family; seq = 0; if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) { XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); goto drop; } do { if (skb->sp->len == XFRM_MAX_DEPTH) if (skb->sp->len == XFRM_MAX_DEPTH) { XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); goto drop; } x = xfrm_state_lookup(daddr, spi, nexthdr, family); if (x == NULL) if (x == NULL) { XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); goto drop; } skb->sp->xvec[skb->sp->len++] = x; spin_lock(&x->lock); if (unlikely(x->km.state != XFRM_STATE_VALID)) if (unlikely(x->km.state != XFRM_STATE_VALID)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); goto drop_unlock; } if ((x->encap ? x->encap->encap_type : 0) != encap_type) if ((x->encap ? x->encap->encap_type : 0) != encap_type) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); goto drop_unlock; } if (x->props.replay_window && xfrm_replay_check(x, seq)) if (x->props.replay_window && xfrm_replay_check(x, seq)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW); goto drop_unlock; } if (xfrm_state_check_expire(x)) if (xfrm_state_check_expire(x)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED); goto drop_unlock; } spin_unlock(&x->lock); Loading @@ -171,6 +187,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) if (nexthdr <= 0) { if (nexthdr == -EBADMSG) x->stats.integrity_failed++; XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR); goto drop_unlock; } Loading @@ -187,8 +204,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; if (x->inner_mode->input(x, skb)) if (x->inner_mode->input(x, skb)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR); goto drop; } if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { decaps = 1; Loading @@ -203,8 +222,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) family = x->outer_mode->afinfo->family; err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); if (err < 0) if (err < 0) { XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); goto drop; } } while (!err); nf_reset(skb); Loading
net/xfrm/xfrm_output.c +5 −1 Original line number Diff line number Diff line Loading @@ -69,10 +69,13 @@ static int xfrm_output_one(struct sk_buff *skb, int err) err = x->type->output(x, skb); resume: if (err) if (err) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR); goto error_nolock; } if (!(skb->dst = dst_pop(dst))) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); err = -EHOSTUNREACH; goto error_nolock; } Loading Loading @@ -167,6 +170,7 @@ int xfrm_output(struct sk_buff *skb) if (skb->ip_summed == CHECKSUM_PARTIAL) { err = skb_checksum_help(skb); if (err) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); kfree_skb(skb); return err; } Loading
net/xfrm/xfrm_policy.c +51 −12 Original line number Diff line number Diff line Loading @@ -1494,9 +1494,11 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); err = PTR_ERR(policy); if (IS_ERR(policy)) if (IS_ERR(policy)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); goto dropdst; } } if (!policy) { /* To accelerate a bit... */ Loading Loading @@ -1529,6 +1531,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, default: case XFRM_POLICY_BLOCK: /* Prohibit the flow */ XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); err = -EPERM; goto error; Loading @@ -1548,6 +1551,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, */ dst = xfrm_find_bundle(fl, policy, family); if (IS_ERR(dst)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); err = PTR_ERR(dst); goto error; } Loading @@ -1562,10 +1566,12 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, XFRM_POLICY_OUT); if (pols[1]) { if (IS_ERR(pols[1])) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); err = PTR_ERR(pols[1]); goto error; } if (pols[1]->action == XFRM_POLICY_BLOCK) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); err = -EPERM; goto error; } Loading Loading @@ -1611,6 +1617,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family); if (nx == -EAGAIN && signal_pending(current)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); err = -ERESTART; goto error; } Loading @@ -1621,9 +1628,11 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, } err = nx; } if (err < 0) if (err < 0) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); goto error; } } if (nx == 0) { /* Flow passes not transformed. */ xfrm_pols_put(pols, npols); Loading @@ -1632,8 +1641,10 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig); err = PTR_ERR(dst); if (IS_ERR(dst)) if (IS_ERR(dst)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR); goto error; } for (pi = 0; pi < npols; pi++) { read_lock_bh(&pols[pi]->lock); Loading @@ -1652,6 +1663,10 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, if (dst) dst_free(dst); if (pol_dead) XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD); else XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); err = -EHOSTUNREACH; goto error; } Loading @@ -1664,6 +1679,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, write_unlock_bh(&policy->lock); if (dst) dst_free(dst); XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); goto error; } Loading Loading @@ -1817,8 +1833,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, dir &= XFRM_POLICY_MASK; fl_dir = policy_to_flow_dir(dir); if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) { XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); return 0; } nf_nat_decode_session(skb, &fl, family); /* First, check used SA against their selectors. */ Loading @@ -1827,28 +1846,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, for (i=skb->sp->len-1; i>=0; i--) { struct xfrm_state *x = skb->sp->xvec[i]; if (!xfrm_selector_match(&x->sel, &fl, family)) if (!xfrm_selector_match(&x->sel, &fl, family)) { XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH); return 0; } } } pol = NULL; if (sk && sk->sk_policy[dir]) { pol = xfrm_sk_policy_lookup(sk, dir, &fl); if (IS_ERR(pol)) if (IS_ERR(pol)) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); return 0; } } if (!pol) pol = flow_cache_lookup(&fl, family, fl_dir, xfrm_policy_lookup); if (IS_ERR(pol)) if (IS_ERR(pol)) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); return 0; } if (!pol) { if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { xfrm_secpath_reject(xerr_idx, skb, &fl); XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS); return 0; } return 1; Loading @@ -1864,8 +1890,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, &fl, family, XFRM_POLICY_IN); if (pols[1]) { if (IS_ERR(pols[1])) if (IS_ERR(pols[1])) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); return 0; } pols[1]->curlft.use_time = get_seconds(); npols ++; } Loading @@ -1886,10 +1914,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, for (pi = 0; pi < npols; pi++) { if (pols[pi] != pol && pols[pi]->action != XFRM_POLICY_ALLOW) pols[pi]->action != XFRM_POLICY_ALLOW) { XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); goto reject; if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) } if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) { XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); goto reject_error; } for (i = 0; i < pols[pi]->xfrm_nr; i++) tpp[ti++] = &pols[pi]->xfrm_vec[i]; } Loading @@ -1911,16 +1943,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, if (k < -1) /* "-2 - errored_index" returned */ xerr_idx = -(2+k); XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); goto reject; } } if (secpath_has_nontransport(sp, k, &xerr_idx)) if (secpath_has_nontransport(sp, k, &xerr_idx)) { XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); goto reject; } xfrm_pols_put(pols, npols); return 1; } XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); reject: xfrm_secpath_reject(xerr_idx, skb, &fl); Loading @@ -1934,8 +1970,11 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) { struct flowi fl; if (xfrm_decode_session(skb, &fl, family) < 0) if (xfrm_decode_session(skb, &fl, family) < 0) { /* XXX: we should have something like FWDHDRERROR here. */ XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); return 0; } return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0; } Loading