diff options
| -rw-r--r-- | net/ipv6/xfrm6_input.c | 3 | ||||
| -rw-r--r-- | net/xfrm/xfrm_input.c | 41 | ||||
| -rw-r--r-- | net/xfrm/xfrm_output.c | 6 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 63 |
4 files changed, 90 insertions, 23 deletions
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index f835ab458f5b..6644fc6d5427 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
| @@ -72,6 +72,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
| 72 | 72 | ||
| 73 | sp = secpath_dup(skb->sp); | 73 | sp = secpath_dup(skb->sp); |
| 74 | if (!sp) { | 74 | if (!sp) { |
| 75 | XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); | ||
| 75 | goto drop; | 76 | goto drop; |
| 76 | } | 77 | } |
| 77 | if (skb->sp) | 78 | if (skb->sp) |
| @@ -80,6 +81,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | if (1 + skb->sp->len == XFRM_MAX_DEPTH) { | 83 | if (1 + skb->sp->len == XFRM_MAX_DEPTH) { |
| 84 | XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); | ||
| 83 | goto drop; | 85 | goto drop; |
| 84 | } | 86 | } |
| 85 | 87 | ||
| @@ -149,6 +151,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
| 149 | } | 151 | } |
| 150 | 152 | ||
| 151 | if (!x) { | 153 | if (!x) { |
| 154 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); | ||
| 152 | goto drop; | 155 | goto drop; |
| 153 | } | 156 | } |
| 154 | 157 | ||
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 8624cbdb2a1e..493243fc5fe5 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
| @@ -119,8 +119,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
| 119 | struct sec_path *sp; | 119 | struct sec_path *sp; |
| 120 | 120 | ||
| 121 | sp = secpath_dup(skb->sp); | 121 | sp = secpath_dup(skb->sp); |
| 122 | if (!sp) | 122 | if (!sp) { |
| 123 | XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); | ||
| 123 | goto drop; | 124 | goto drop; |
| 125 | } | ||
| 124 | if (skb->sp) | 126 | if (skb->sp) |
| 125 | secpath_put(skb->sp); | 127 | secpath_put(skb->sp); |
| 126 | skb->sp = sp; | 128 | skb->sp = sp; |
| @@ -131,31 +133,45 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
| 131 | family = XFRM_SPI_SKB_CB(skb)->family; | 133 | family = XFRM_SPI_SKB_CB(skb)->family; |
| 132 | 134 | ||
| 133 | seq = 0; | 135 | seq = 0; |
| 134 | if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) | 136 | if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) { |
| 137 | XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); | ||
| 135 | goto drop; | 138 | goto drop; |
| 139 | } | ||
| 136 | 140 | ||
| 137 | do { | 141 | do { |
| 138 | if (skb->sp->len == XFRM_MAX_DEPTH) | 142 | if (skb->sp->len == XFRM_MAX_DEPTH) { |
| 143 | XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); | ||
| 139 | goto drop; | 144 | goto drop; |
| 145 | } | ||
| 140 | 146 | ||
| 141 | x = xfrm_state_lookup(daddr, spi, nexthdr, family); | 147 | x = xfrm_state_lookup(daddr, spi, nexthdr, family); |
| 142 | if (x == NULL) | 148 | if (x == NULL) { |
| 149 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); | ||
| 143 | goto drop; | 150 | goto drop; |
| 151 | } | ||
| 144 | 152 | ||
| 145 | skb->sp->xvec[skb->sp->len++] = x; | 153 | skb->sp->xvec[skb->sp->len++] = x; |
| 146 | 154 | ||
| 147 | spin_lock(&x->lock); | 155 | spin_lock(&x->lock); |
| 148 | if (unlikely(x->km.state != XFRM_STATE_VALID)) | 156 | if (unlikely(x->km.state != XFRM_STATE_VALID)) { |
| 157 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); | ||
| 149 | goto drop_unlock; | 158 | goto drop_unlock; |
| 159 | } | ||
| 150 | 160 | ||
| 151 | if ((x->encap ? x->encap->encap_type : 0) != encap_type) | 161 | if ((x->encap ? x->encap->encap_type : 0) != encap_type) { |
| 162 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); | ||
| 152 | goto drop_unlock; | 163 | goto drop_unlock; |
| 164 | } | ||
| 153 | 165 | ||
| 154 | if (x->props.replay_window && xfrm_replay_check(x, seq)) | 166 | if (x->props.replay_window && xfrm_replay_check(x, seq)) { |
| 167 | XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW); | ||
| 155 | goto drop_unlock; | 168 | goto drop_unlock; |
| 169 | } | ||
| 156 | 170 | ||
| 157 | if (xfrm_state_check_expire(x)) | 171 | if (xfrm_state_check_expire(x)) { |
| 172 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED); | ||
| 158 | goto drop_unlock; | 173 | goto drop_unlock; |
| 174 | } | ||
| 159 | 175 | ||
| 160 | spin_unlock(&x->lock); | 176 | spin_unlock(&x->lock); |
| 161 | 177 | ||
| @@ -171,6 +187,7 @@ resume: | |||
| 171 | if (nexthdr <= 0) { | 187 | if (nexthdr <= 0) { |
| 172 | if (nexthdr == -EBADMSG) | 188 | if (nexthdr == -EBADMSG) |
| 173 | x->stats.integrity_failed++; | 189 | x->stats.integrity_failed++; |
| 190 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR); | ||
| 174 | goto drop_unlock; | 191 | goto drop_unlock; |
| 175 | } | 192 | } |
| 176 | 193 | ||
| @@ -187,8 +204,10 @@ resume: | |||
| 187 | 204 | ||
| 188 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; | 205 | XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; |
| 189 | 206 | ||
| 190 | if (x->inner_mode->input(x, skb)) | 207 | if (x->inner_mode->input(x, skb)) { |
| 208 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR); | ||
| 191 | goto drop; | 209 | goto drop; |
| 210 | } | ||
| 192 | 211 | ||
| 193 | if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { | 212 | if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { |
| 194 | decaps = 1; | 213 | decaps = 1; |
| @@ -203,8 +222,10 @@ resume: | |||
| 203 | family = x->outer_mode->afinfo->family; | 222 | family = x->outer_mode->afinfo->family; |
| 204 | 223 | ||
| 205 | err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); | 224 | err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); |
| 206 | if (err < 0) | 225 | if (err < 0) { |
| 226 | XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); | ||
| 207 | goto drop; | 227 | goto drop; |
| 228 | } | ||
| 208 | } while (!err); | 229 | } while (!err); |
| 209 | 230 | ||
| 210 | nf_reset(skb); | 231 | nf_reset(skb); |
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 26fa0cb78c94..867484a046af 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
| @@ -69,10 +69,13 @@ static int xfrm_output_one(struct sk_buff *skb, int err) | |||
| 69 | err = x->type->output(x, skb); | 69 | err = x->type->output(x, skb); |
| 70 | 70 | ||
| 71 | resume: | 71 | resume: |
| 72 | if (err) | 72 | if (err) { |
| 73 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR); | ||
| 73 | goto error_nolock; | 74 | goto error_nolock; |
| 75 | } | ||
| 74 | 76 | ||
| 75 | if (!(skb->dst = dst_pop(dst))) { | 77 | if (!(skb->dst = dst_pop(dst))) { |
| 78 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); | ||
| 76 | err = -EHOSTUNREACH; | 79 | err = -EHOSTUNREACH; |
| 77 | goto error_nolock; | 80 | goto error_nolock; |
| 78 | } | 81 | } |
| @@ -167,6 +170,7 @@ int xfrm_output(struct sk_buff *skb) | |||
| 167 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 170 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 168 | err = skb_checksum_help(skb); | 171 | err = skb_checksum_help(skb); |
| 169 | if (err) { | 172 | if (err) { |
| 173 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); | ||
| 170 | kfree_skb(skb); | 174 | kfree_skb(skb); |
| 171 | return err; | 175 | return err; |
| 172 | } | 176 | } |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 32ddb7b12e7f..74807a7d3d69 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1494,8 +1494,10 @@ restart: | |||
| 1494 | if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { | 1494 | if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { |
| 1495 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); | 1495 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); |
| 1496 | err = PTR_ERR(policy); | 1496 | err = PTR_ERR(policy); |
| 1497 | if (IS_ERR(policy)) | 1497 | if (IS_ERR(policy)) { |
| 1498 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); | ||
| 1498 | goto dropdst; | 1499 | goto dropdst; |
| 1500 | } | ||
| 1499 | } | 1501 | } |
| 1500 | 1502 | ||
| 1501 | if (!policy) { | 1503 | if (!policy) { |
| @@ -1529,6 +1531,7 @@ restart: | |||
| 1529 | default: | 1531 | default: |
| 1530 | case XFRM_POLICY_BLOCK: | 1532 | case XFRM_POLICY_BLOCK: |
| 1531 | /* Prohibit the flow */ | 1533 | /* Prohibit the flow */ |
| 1534 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); | ||
| 1532 | err = -EPERM; | 1535 | err = -EPERM; |
| 1533 | goto error; | 1536 | goto error; |
| 1534 | 1537 | ||
| @@ -1548,6 +1551,7 @@ restart: | |||
| 1548 | */ | 1551 | */ |
| 1549 | dst = xfrm_find_bundle(fl, policy, family); | 1552 | dst = xfrm_find_bundle(fl, policy, family); |
| 1550 | if (IS_ERR(dst)) { | 1553 | if (IS_ERR(dst)) { |
| 1554 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); | ||
| 1551 | err = PTR_ERR(dst); | 1555 | err = PTR_ERR(dst); |
| 1552 | goto error; | 1556 | goto error; |
| 1553 | } | 1557 | } |
| @@ -1562,10 +1566,12 @@ restart: | |||
| 1562 | XFRM_POLICY_OUT); | 1566 | XFRM_POLICY_OUT); |
| 1563 | if (pols[1]) { | 1567 | if (pols[1]) { |
| 1564 | if (IS_ERR(pols[1])) { | 1568 | if (IS_ERR(pols[1])) { |
| 1569 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); | ||
| 1565 | err = PTR_ERR(pols[1]); | 1570 | err = PTR_ERR(pols[1]); |
| 1566 | goto error; | 1571 | goto error; |
| 1567 | } | 1572 | } |
| 1568 | if (pols[1]->action == XFRM_POLICY_BLOCK) { | 1573 | if (pols[1]->action == XFRM_POLICY_BLOCK) { |
| 1574 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); | ||
| 1569 | err = -EPERM; | 1575 | err = -EPERM; |
| 1570 | goto error; | 1576 | goto error; |
| 1571 | } | 1577 | } |
| @@ -1611,6 +1617,7 @@ restart: | |||
| 1611 | nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family); | 1617 | nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family); |
| 1612 | 1618 | ||
| 1613 | if (nx == -EAGAIN && signal_pending(current)) { | 1619 | if (nx == -EAGAIN && signal_pending(current)) { |
| 1620 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); | ||
| 1614 | err = -ERESTART; | 1621 | err = -ERESTART; |
| 1615 | goto error; | 1622 | goto error; |
| 1616 | } | 1623 | } |
| @@ -1621,8 +1628,10 @@ restart: | |||
| 1621 | } | 1628 | } |
| 1622 | err = nx; | 1629 | err = nx; |
| 1623 | } | 1630 | } |
| 1624 | if (err < 0) | 1631 | if (err < 0) { |
| 1632 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); | ||
| 1625 | goto error; | 1633 | goto error; |
| 1634 | } | ||
| 1626 | } | 1635 | } |
| 1627 | if (nx == 0) { | 1636 | if (nx == 0) { |
| 1628 | /* Flow passes not transformed. */ | 1637 | /* Flow passes not transformed. */ |
| @@ -1632,8 +1641,10 @@ restart: | |||
| 1632 | 1641 | ||
| 1633 | dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig); | 1642 | dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig); |
| 1634 | err = PTR_ERR(dst); | 1643 | err = PTR_ERR(dst); |
| 1635 | if (IS_ERR(dst)) | 1644 | if (IS_ERR(dst)) { |
| 1645 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR); | ||
| 1636 | goto error; | 1646 | goto error; |
| 1647 | } | ||
| 1637 | 1648 | ||
| 1638 | for (pi = 0; pi < npols; pi++) { | 1649 | for (pi = 0; pi < npols; pi++) { |
| 1639 | read_lock_bh(&pols[pi]->lock); | 1650 | read_lock_bh(&pols[pi]->lock); |
| @@ -1652,6 +1663,10 @@ restart: | |||
| 1652 | if (dst) | 1663 | if (dst) |
| 1653 | dst_free(dst); | 1664 | dst_free(dst); |
| 1654 | 1665 | ||
| 1666 | if (pol_dead) | ||
| 1667 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD); | ||
| 1668 | else | ||
| 1669 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); | ||
| 1655 | err = -EHOSTUNREACH; | 1670 | err = -EHOSTUNREACH; |
| 1656 | goto error; | 1671 | goto error; |
| 1657 | } | 1672 | } |
| @@ -1664,6 +1679,7 @@ restart: | |||
| 1664 | write_unlock_bh(&policy->lock); | 1679 | write_unlock_bh(&policy->lock); |
| 1665 | if (dst) | 1680 | if (dst) |
| 1666 | dst_free(dst); | 1681 | dst_free(dst); |
| 1682 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); | ||
| 1667 | goto error; | 1683 | goto error; |
| 1668 | } | 1684 | } |
| 1669 | 1685 | ||
| @@ -1817,8 +1833,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 1817 | dir &= XFRM_POLICY_MASK; | 1833 | dir &= XFRM_POLICY_MASK; |
| 1818 | fl_dir = policy_to_flow_dir(dir); | 1834 | fl_dir = policy_to_flow_dir(dir); |
| 1819 | 1835 | ||
| 1820 | if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) | 1836 | if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) { |
| 1837 | XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); | ||
| 1821 | return 0; | 1838 | return 0; |
| 1839 | } | ||
| 1840 | |||
| 1822 | nf_nat_decode_session(skb, &fl, family); | 1841 | nf_nat_decode_session(skb, &fl, family); |
| 1823 | 1842 | ||
| 1824 | /* First, check used SA against their selectors. */ | 1843 | /* First, check used SA against their selectors. */ |
| @@ -1827,28 +1846,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 1827 | 1846 | ||
| 1828 | for (i=skb->sp->len-1; i>=0; i--) { | 1847 | for (i=skb->sp->len-1; i>=0; i--) { |
| 1829 | struct xfrm_state *x = skb->sp->xvec[i]; | 1848 | struct xfrm_state *x = skb->sp->xvec[i]; |
| 1830 | if (!xfrm_selector_match(&x->sel, &fl, family)) | 1849 | if (!xfrm_selector_match(&x->sel, &fl, family)) { |
| 1850 | XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH); | ||
| 1831 | return 0; | 1851 | return 0; |
| 1852 | } | ||
| 1832 | } | 1853 | } |
| 1833 | } | 1854 | } |
| 1834 | 1855 | ||
| 1835 | pol = NULL; | 1856 | pol = NULL; |
| 1836 | if (sk && sk->sk_policy[dir]) { | 1857 | if (sk && sk->sk_policy[dir]) { |
| 1837 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); | 1858 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); |
| 1838 | if (IS_ERR(pol)) | 1859 | if (IS_ERR(pol)) { |
| 1860 | XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); | ||
| 1839 | return 0; | 1861 | return 0; |
| 1862 | } | ||
| 1840 | } | 1863 | } |
| 1841 | 1864 | ||
| 1842 | if (!pol) | 1865 | if (!pol) |
| 1843 | pol = flow_cache_lookup(&fl, family, fl_dir, | 1866 | pol = flow_cache_lookup(&fl, family, fl_dir, |
| 1844 | xfrm_policy_lookup); | 1867 | xfrm_policy_lookup); |
| 1845 | 1868 | ||
| 1846 | if (IS_ERR(pol)) | 1869 | if (IS_ERR(pol)) { |
| 1870 | XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); | ||
| 1847 | return 0; | 1871 | return 0; |
| 1872 | } | ||
| 1848 | 1873 | ||
| 1849 | if (!pol) { | 1874 | if (!pol) { |
| 1850 | if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { | 1875 | if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { |
| 1851 | xfrm_secpath_reject(xerr_idx, skb, &fl); | 1876 | xfrm_secpath_reject(xerr_idx, skb, &fl); |
| 1877 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS); | ||
| 1852 | return 0; | 1878 | return 0; |
| 1853 | } | 1879 | } |
| 1854 | return 1; | 1880 | return 1; |
| @@ -1864,8 +1890,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 1864 | &fl, family, | 1890 | &fl, family, |
| 1865 | XFRM_POLICY_IN); | 1891 | XFRM_POLICY_IN); |
| 1866 | if (pols[1]) { | 1892 | if (pols[1]) { |
| 1867 | if (IS_ERR(pols[1])) | 1893 | if (IS_ERR(pols[1])) { |
| 1894 | XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); | ||
| 1868 | return 0; | 1895 | return 0; |
| 1896 | } | ||
| 1869 | pols[1]->curlft.use_time = get_seconds(); | 1897 | pols[1]->curlft.use_time = get_seconds(); |
| 1870 | npols ++; | 1898 | npols ++; |
| 1871 | } | 1899 | } |
| @@ -1886,10 +1914,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 1886 | 1914 | ||
| 1887 | for (pi = 0; pi < npols; pi++) { | 1915 | for (pi = 0; pi < npols; pi++) { |
| 1888 | if (pols[pi] != pol && | 1916 | if (pols[pi] != pol && |
| 1889 | pols[pi]->action != XFRM_POLICY_ALLOW) | 1917 | pols[pi]->action != XFRM_POLICY_ALLOW) { |
| 1918 | XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); | ||
| 1890 | goto reject; | 1919 | goto reject; |
| 1891 | if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) | 1920 | } |
| 1921 | if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) { | ||
| 1922 | XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); | ||
| 1892 | goto reject_error; | 1923 | goto reject_error; |
| 1924 | } | ||
| 1893 | for (i = 0; i < pols[pi]->xfrm_nr; i++) | 1925 | for (i = 0; i < pols[pi]->xfrm_nr; i++) |
| 1894 | tpp[ti++] = &pols[pi]->xfrm_vec[i]; | 1926 | tpp[ti++] = &pols[pi]->xfrm_vec[i]; |
| 1895 | } | 1927 | } |
| @@ -1911,16 +1943,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 1911 | if (k < -1) | 1943 | if (k < -1) |
| 1912 | /* "-2 - errored_index" returned */ | 1944 | /* "-2 - errored_index" returned */ |
| 1913 | xerr_idx = -(2+k); | 1945 | xerr_idx = -(2+k); |
| 1946 | XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); | ||
| 1914 | goto reject; | 1947 | goto reject; |
| 1915 | } | 1948 | } |
| 1916 | } | 1949 | } |
| 1917 | 1950 | ||
| 1918 | if (secpath_has_nontransport(sp, k, &xerr_idx)) | 1951 | if (secpath_has_nontransport(sp, k, &xerr_idx)) { |
| 1952 | XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); | ||
| 1919 | goto reject; | 1953 | goto reject; |
| 1954 | } | ||
| 1920 | 1955 | ||
| 1921 | xfrm_pols_put(pols, npols); | 1956 | xfrm_pols_put(pols, npols); |
| 1922 | return 1; | 1957 | return 1; |
| 1923 | } | 1958 | } |
| 1959 | XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); | ||
| 1924 | 1960 | ||
| 1925 | reject: | 1961 | reject: |
| 1926 | xfrm_secpath_reject(xerr_idx, skb, &fl); | 1962 | xfrm_secpath_reject(xerr_idx, skb, &fl); |
| @@ -1934,8 +1970,11 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) | |||
| 1934 | { | 1970 | { |
| 1935 | struct flowi fl; | 1971 | struct flowi fl; |
| 1936 | 1972 | ||
| 1937 | if (xfrm_decode_session(skb, &fl, family) < 0) | 1973 | if (xfrm_decode_session(skb, &fl, family) < 0) { |
| 1974 | /* XXX: we should have something like FWDHDRERROR here. */ | ||
| 1975 | XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); | ||
| 1938 | return 0; | 1976 | return 0; |
| 1977 | } | ||
| 1939 | 1978 | ||
| 1940 | return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0; | 1979 | return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0; |
| 1941 | } | 1980 | } |
