aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r--net/xfrm/xfrm_state.c190
1 files changed, 55 insertions, 135 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 220ebc05c7a..f83a3d1da81 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -42,16 +42,9 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
42static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family); 42static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
43static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); 43static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
44 44
45#ifdef CONFIG_AUDITSYSCALL
46static void xfrm_audit_state_replay(struct xfrm_state *x,
47 struct sk_buff *skb, __be32 net_seq);
48#else
49#define xfrm_audit_state_replay(x, s, sq) do { ; } while (0)
50#endif /* CONFIG_AUDITSYSCALL */
51
52static inline unsigned int xfrm_dst_hash(struct net *net, 45static inline unsigned int xfrm_dst_hash(struct net *net,
53 xfrm_address_t *daddr, 46 const xfrm_address_t *daddr,
54 xfrm_address_t *saddr, 47 const xfrm_address_t *saddr,
55 u32 reqid, 48 u32 reqid,
56 unsigned short family) 49 unsigned short family)
57{ 50{
@@ -59,15 +52,16 @@ static inline unsigned int xfrm_dst_hash(struct net *net,
59} 52}
60 53
61static inline unsigned int xfrm_src_hash(struct net *net, 54static inline unsigned int xfrm_src_hash(struct net *net,
62 xfrm_address_t *daddr, 55 const xfrm_address_t *daddr,
63 xfrm_address_t *saddr, 56 const xfrm_address_t *saddr,
64 unsigned short family) 57 unsigned short family)
65{ 58{
66 return __xfrm_src_hash(daddr, saddr, family, net->xfrm.state_hmask); 59 return __xfrm_src_hash(daddr, saddr, family, net->xfrm.state_hmask);
67} 60}
68 61
69static inline unsigned int 62static inline unsigned int
70xfrm_spi_hash(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) 63xfrm_spi_hash(struct net *net, const xfrm_address_t *daddr,
64 __be32 spi, u8 proto, unsigned short family)
71{ 65{
72 return __xfrm_spi_hash(daddr, spi, proto, family, net->xfrm.state_hmask); 66 return __xfrm_spi_hash(daddr, spi, proto, family, net->xfrm.state_hmask);
73} 67}
@@ -362,6 +356,8 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
362 kfree(x->calg); 356 kfree(x->calg);
363 kfree(x->encap); 357 kfree(x->encap);
364 kfree(x->coaddr); 358 kfree(x->coaddr);
359 kfree(x->replay_esn);
360 kfree(x->preplay_esn);
365 if (x->inner_mode) 361 if (x->inner_mode)
366 xfrm_put_mode(x->inner_mode); 362 xfrm_put_mode(x->inner_mode);
367 if (x->inner_mode_iaf) 363 if (x->inner_mode_iaf)
@@ -656,9 +652,9 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
656EXPORT_SYMBOL(xfrm_sad_getinfo); 652EXPORT_SYMBOL(xfrm_sad_getinfo);
657 653
658static int 654static int
659xfrm_init_tempstate(struct xfrm_state *x, struct flowi *fl, 655xfrm_init_tempstate(struct xfrm_state *x, const struct flowi *fl,
660 struct xfrm_tmpl *tmpl, 656 const struct xfrm_tmpl *tmpl,
661 xfrm_address_t *daddr, xfrm_address_t *saddr, 657 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
662 unsigned short family) 658 unsigned short family)
663{ 659{
664 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 660 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
@@ -677,7 +673,10 @@ xfrm_init_tempstate(struct xfrm_state *x, struct flowi *fl,
677 return 0; 673 return 0;
678} 674}
679 675
680static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) 676static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark,
677 const xfrm_address_t *daddr,
678 __be32 spi, u8 proto,
679 unsigned short family)
681{ 680{
682 unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); 681 unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
683 struct xfrm_state *x; 682 struct xfrm_state *x;
@@ -699,7 +698,10 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_ad
699 return NULL; 698 return NULL;
700} 699}
701 700
702static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) 701static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark,
702 const xfrm_address_t *daddr,
703 const xfrm_address_t *saddr,
704 u8 proto, unsigned short family)
703{ 705{
704 unsigned int h = xfrm_src_hash(net, daddr, saddr, family); 706 unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
705 struct xfrm_state *x; 707 struct xfrm_state *x;
@@ -746,8 +748,7 @@ static void xfrm_hash_grow_check(struct net *net, int have_hash_collision)
746} 748}
747 749
748static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x, 750static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
749 struct flowi *fl, unsigned short family, 751 const struct flowi *fl, unsigned short family,
750 xfrm_address_t *daddr, xfrm_address_t *saddr,
751 struct xfrm_state **best, int *acq_in_progress, 752 struct xfrm_state **best, int *acq_in_progress,
752 int *error) 753 int *error)
753{ 754{
@@ -784,8 +785,8 @@ static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
784} 785}
785 786
786struct xfrm_state * 787struct xfrm_state *
787xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 788xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
788 struct flowi *fl, struct xfrm_tmpl *tmpl, 789 const struct flowi *fl, struct xfrm_tmpl *tmpl,
789 struct xfrm_policy *pol, int *err, 790 struct xfrm_policy *pol, int *err,
790 unsigned short family) 791 unsigned short family)
791{ 792{
@@ -813,7 +814,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
813 tmpl->mode == x->props.mode && 814 tmpl->mode == x->props.mode &&
814 tmpl->id.proto == x->id.proto && 815 tmpl->id.proto == x->id.proto &&
815 (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) 816 (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
816 xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, 817 xfrm_state_look_at(pol, x, fl, encap_family,
817 &best, &acquire_in_progress, &error); 818 &best, &acquire_in_progress, &error);
818 } 819 }
819 if (best) 820 if (best)
@@ -829,7 +830,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
829 tmpl->mode == x->props.mode && 830 tmpl->mode == x->props.mode &&
830 tmpl->id.proto == x->id.proto && 831 tmpl->id.proto == x->id.proto &&
831 (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) 832 (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
832 xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, 833 xfrm_state_look_at(pol, x, fl, encap_family,
833 &best, &acquire_in_progress, &error); 834 &best, &acquire_in_progress, &error);
834 } 835 }
835 836
@@ -853,7 +854,7 @@ found:
853 xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family); 854 xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family);
854 memcpy(&x->mark, &pol->mark, sizeof(x->mark)); 855 memcpy(&x->mark, &pol->mark, sizeof(x->mark));
855 856
856 error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); 857 error = security_xfrm_state_alloc_acquire(x, pol->security, fl->flowi_secid);
857 if (error) { 858 if (error) {
858 x->km.state = XFRM_STATE_DEAD; 859 x->km.state = XFRM_STATE_DEAD;
859 to_put = x; 860 to_put = x;
@@ -991,7 +992,11 @@ void xfrm_state_insert(struct xfrm_state *x)
991EXPORT_SYMBOL(xfrm_state_insert); 992EXPORT_SYMBOL(xfrm_state_insert);
992 993
993/* xfrm_state_lock is held */ 994/* xfrm_state_lock is held */
994static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create) 995static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m,
996 unsigned short family, u8 mode,
997 u32 reqid, u8 proto,
998 const xfrm_address_t *daddr,
999 const xfrm_address_t *saddr, int create)
995{ 1000{
996 unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family); 1001 unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
997 struct hlist_node *entry; 1002 struct hlist_node *entry;
@@ -1369,7 +1374,7 @@ int xfrm_state_check_expire(struct xfrm_state *x)
1369EXPORT_SYMBOL(xfrm_state_check_expire); 1374EXPORT_SYMBOL(xfrm_state_check_expire);
1370 1375
1371struct xfrm_state * 1376struct xfrm_state *
1372xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, 1377xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi,
1373 u8 proto, unsigned short family) 1378 u8 proto, unsigned short family)
1374{ 1379{
1375 struct xfrm_state *x; 1380 struct xfrm_state *x;
@@ -1383,7 +1388,7 @@ EXPORT_SYMBOL(xfrm_state_lookup);
1383 1388
1384struct xfrm_state * 1389struct xfrm_state *
1385xfrm_state_lookup_byaddr(struct net *net, u32 mark, 1390xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1386 xfrm_address_t *daddr, xfrm_address_t *saddr, 1391 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
1387 u8 proto, unsigned short family) 1392 u8 proto, unsigned short family)
1388{ 1393{
1389 struct xfrm_state *x; 1394 struct xfrm_state *x;
@@ -1397,7 +1402,7 @@ EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
1397 1402
1398struct xfrm_state * 1403struct xfrm_state *
1399xfrm_find_acq(struct net *net, struct xfrm_mark *mark, u8 mode, u32 reqid, u8 proto, 1404xfrm_find_acq(struct net *net, struct xfrm_mark *mark, u8 mode, u32 reqid, u8 proto,
1400 xfrm_address_t *daddr, xfrm_address_t *saddr, 1405 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
1401 int create, unsigned short family) 1406 int create, unsigned short family)
1402{ 1407{
1403 struct xfrm_state *x; 1408 struct xfrm_state *x;
@@ -1609,54 +1614,6 @@ void xfrm_state_walk_done(struct xfrm_state_walk *walk)
1609} 1614}
1610EXPORT_SYMBOL(xfrm_state_walk_done); 1615EXPORT_SYMBOL(xfrm_state_walk_done);
1611 1616
1612
1613void xfrm_replay_notify(struct xfrm_state *x, int event)
1614{
1615 struct km_event c;
1616 /* we send notify messages in case
1617 * 1. we updated on of the sequence numbers, and the seqno difference
1618 * is at least x->replay_maxdiff, in this case we also update the
1619 * timeout of our timer function
1620 * 2. if x->replay_maxage has elapsed since last update,
1621 * and there were changes
1622 *
1623 * The state structure must be locked!
1624 */
1625
1626 switch (event) {
1627 case XFRM_REPLAY_UPDATE:
1628 if (x->replay_maxdiff &&
1629 (x->replay.seq - x->preplay.seq < x->replay_maxdiff) &&
1630 (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff)) {
1631 if (x->xflags & XFRM_TIME_DEFER)
1632 event = XFRM_REPLAY_TIMEOUT;
1633 else
1634 return;
1635 }
1636
1637 break;
1638
1639 case XFRM_REPLAY_TIMEOUT:
1640 if ((x->replay.seq == x->preplay.seq) &&
1641 (x->replay.bitmap == x->preplay.bitmap) &&
1642 (x->replay.oseq == x->preplay.oseq)) {
1643 x->xflags |= XFRM_TIME_DEFER;
1644 return;
1645 }
1646
1647 break;
1648 }
1649
1650 memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state));
1651 c.event = XFRM_MSG_NEWAE;
1652 c.data.aevent = event;
1653 km_state_notify(x, &c);
1654
1655 if (x->replay_maxage &&
1656 !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
1657 x->xflags &= ~XFRM_TIME_DEFER;
1658}
1659
1660static void xfrm_replay_timer_handler(unsigned long data) 1617static void xfrm_replay_timer_handler(unsigned long data)
1661{ 1618{
1662 struct xfrm_state *x = (struct xfrm_state*)data; 1619 struct xfrm_state *x = (struct xfrm_state*)data;
@@ -1665,7 +1622,7 @@ static void xfrm_replay_timer_handler(unsigned long data)
1665 1622
1666 if (x->km.state == XFRM_STATE_VALID) { 1623 if (x->km.state == XFRM_STATE_VALID) {
1667 if (xfrm_aevent_is_on(xs_net(x))) 1624 if (xfrm_aevent_is_on(xs_net(x)))
1668 xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT); 1625 x->repl->notify(x, XFRM_REPLAY_TIMEOUT);
1669 else 1626 else
1670 x->xflags |= XFRM_TIME_DEFER; 1627 x->xflags |= XFRM_TIME_DEFER;
1671 } 1628 }
@@ -1673,61 +1630,10 @@ static void xfrm_replay_timer_handler(unsigned long data)
1673 spin_unlock(&x->lock); 1630 spin_unlock(&x->lock);
1674} 1631}
1675 1632
1676int xfrm_replay_check(struct xfrm_state *x,
1677 struct sk_buff *skb, __be32 net_seq)
1678{
1679 u32 diff;
1680 u32 seq = ntohl(net_seq);
1681
1682 if (unlikely(seq == 0))
1683 goto err;
1684
1685 if (likely(seq > x->replay.seq))
1686 return 0;
1687
1688 diff = x->replay.seq - seq;
1689 if (diff >= min_t(unsigned int, x->props.replay_window,
1690 sizeof(x->replay.bitmap) * 8)) {
1691 x->stats.replay_window++;
1692 goto err;
1693 }
1694
1695 if (x->replay.bitmap & (1U << diff)) {
1696 x->stats.replay++;
1697 goto err;
1698 }
1699 return 0;
1700
1701err:
1702 xfrm_audit_state_replay(x, skb, net_seq);
1703 return -EINVAL;
1704}
1705
1706void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
1707{
1708 u32 diff;
1709 u32 seq = ntohl(net_seq);
1710
1711 if (seq > x->replay.seq) {
1712 diff = seq - x->replay.seq;
1713 if (diff < x->props.replay_window)
1714 x->replay.bitmap = ((x->replay.bitmap) << diff) | 1;
1715 else
1716 x->replay.bitmap = 1;
1717 x->replay.seq = seq;
1718 } else {
1719 diff = x->replay.seq - seq;
1720 x->replay.bitmap |= (1U << diff);
1721 }
1722
1723 if (xfrm_aevent_is_on(xs_net(x)))
1724 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
1725}
1726
1727static LIST_HEAD(xfrm_km_list); 1633static LIST_HEAD(xfrm_km_list);
1728static DEFINE_RWLOCK(xfrm_km_lock); 1634static DEFINE_RWLOCK(xfrm_km_lock);
1729 1635
1730void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) 1636void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c)
1731{ 1637{
1732 struct xfrm_mgr *km; 1638 struct xfrm_mgr *km;
1733 1639
@@ -1738,7 +1644,7 @@ void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
1738 read_unlock(&xfrm_km_lock); 1644 read_unlock(&xfrm_km_lock);
1739} 1645}
1740 1646
1741void km_state_notify(struct xfrm_state *x, struct km_event *c) 1647void km_state_notify(struct xfrm_state *x, const struct km_event *c)
1742{ 1648{
1743 struct xfrm_mgr *km; 1649 struct xfrm_mgr *km;
1744 read_lock(&xfrm_km_lock); 1650 read_lock(&xfrm_km_lock);
@@ -1819,9 +1725,9 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid)
1819EXPORT_SYMBOL(km_policy_expired); 1725EXPORT_SYMBOL(km_policy_expired);
1820 1726
1821#ifdef CONFIG_XFRM_MIGRATE 1727#ifdef CONFIG_XFRM_MIGRATE
1822int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 1728int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1823 struct xfrm_migrate *m, int num_migrate, 1729 const struct xfrm_migrate *m, int num_migrate,
1824 struct xfrm_kmaddress *k) 1730 const struct xfrm_kmaddress *k)
1825{ 1731{
1826 int err = -EINVAL; 1732 int err = -EINVAL;
1827 int ret; 1733 int ret;
@@ -2001,7 +1907,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
2001 return res; 1907 return res;
2002} 1908}
2003 1909
2004int xfrm_init_state(struct xfrm_state *x) 1910int __xfrm_init_state(struct xfrm_state *x, bool init_replay)
2005{ 1911{
2006 struct xfrm_state_afinfo *afinfo; 1912 struct xfrm_state_afinfo *afinfo;
2007 struct xfrm_mode *inner_mode; 1913 struct xfrm_mode *inner_mode;
@@ -2074,12 +1980,25 @@ int xfrm_init_state(struct xfrm_state *x)
2074 if (x->outer_mode == NULL) 1980 if (x->outer_mode == NULL)
2075 goto error; 1981 goto error;
2076 1982
1983 if (init_replay) {
1984 err = xfrm_init_replay(x);
1985 if (err)
1986 goto error;
1987 }
1988
2077 x->km.state = XFRM_STATE_VALID; 1989 x->km.state = XFRM_STATE_VALID;
2078 1990
2079error: 1991error:
2080 return err; 1992 return err;
2081} 1993}
2082 1994
1995EXPORT_SYMBOL(__xfrm_init_state);
1996
1997int xfrm_init_state(struct xfrm_state *x)
1998{
1999 return __xfrm_init_state(x, true);
2000}
2001
2083EXPORT_SYMBOL(xfrm_init_state); 2002EXPORT_SYMBOL(xfrm_init_state);
2084 2003
2085int __net_init xfrm_state_init(struct net *net) 2004int __net_init xfrm_state_init(struct net *net)
@@ -2236,7 +2155,7 @@ void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
2236} 2155}
2237EXPORT_SYMBOL_GPL(xfrm_audit_state_replay_overflow); 2156EXPORT_SYMBOL_GPL(xfrm_audit_state_replay_overflow);
2238 2157
2239static void xfrm_audit_state_replay(struct xfrm_state *x, 2158void xfrm_audit_state_replay(struct xfrm_state *x,
2240 struct sk_buff *skb, __be32 net_seq) 2159 struct sk_buff *skb, __be32 net_seq)
2241{ 2160{
2242 struct audit_buffer *audit_buf; 2161 struct audit_buffer *audit_buf;
@@ -2251,6 +2170,7 @@ static void xfrm_audit_state_replay(struct xfrm_state *x,
2251 spi, spi, ntohl(net_seq)); 2170 spi, spi, ntohl(net_seq));
2252 audit_log_end(audit_buf); 2171 audit_log_end(audit_buf);
2253} 2172}
2173EXPORT_SYMBOL_GPL(xfrm_audit_state_replay);
2254 2174
2255void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family) 2175void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family)
2256{ 2176{