Skip to content

Commit a4be47a

Browse files
committed
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2020-09-28 1) Fix a build warning in ip_vti if CONFIG_IPV6 is not set. From YueHaibing. 2) Restore IPCB on espintcp before handing the packet to xfrm as the information there is still needed. From Sabrina Dubroca. 3) Fix pmtu updating for xfrm interfaces. From Sabrina Dubroca. 4) Some xfrm state information was not cloned with xfrm_do_migrate. Fixes to clone the full xfrm state, from Antony Antony. 5) Use the correct address family in xfrm_state_find. The struct flowi must always be interpreted along with the original address family. This got lost over the years. Fix from Herbert Xu. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 709a16b + e94ee17 commit a4be47a

File tree

5 files changed

+51
-17
lines changed

5 files changed

+51
-17
lines changed

include/net/xfrm.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,21 +1773,17 @@ static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_es
17731773
static inline int xfrm_replay_clone(struct xfrm_state *x,
17741774
struct xfrm_state *orig)
17751775
{
1776-
x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
1776+
1777+
x->replay_esn = kmemdup(orig->replay_esn,
1778+
xfrm_replay_state_esn_len(orig->replay_esn),
17771779
GFP_KERNEL);
17781780
if (!x->replay_esn)
17791781
return -ENOMEM;
1780-
1781-
x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
1782-
x->replay_esn->replay_window = orig->replay_esn->replay_window;
1783-
1784-
x->preplay_esn = kmemdup(x->replay_esn,
1785-
xfrm_replay_state_esn_len(x->replay_esn),
1782+
x->preplay_esn = kmemdup(orig->preplay_esn,
1783+
xfrm_replay_state_esn_len(orig->preplay_esn),
17861784
GFP_KERNEL);
1787-
if (!x->preplay_esn) {
1788-
kfree(x->replay_esn);
1785+
if (!x->preplay_esn)
17891786
return -ENOMEM;
1790-
}
17911787

17921788
return 0;
17931789
}

net/ipv4/ip_vti.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,13 +490,15 @@ static struct xfrm_tunnel vti_ipip_handler __read_mostly = {
490490
.priority = 0,
491491
};
492492

493+
#if IS_ENABLED(CONFIG_IPV6)
493494
static struct xfrm_tunnel vti_ipip6_handler __read_mostly = {
494495
.handler = vti_rcv_tunnel,
495496
.cb_handler = vti_rcv_cb,
496497
.err_handler = vti4_err,
497498
.priority = 0,
498499
};
499500
#endif
501+
#endif
500502

501503
static int __net_init vti_init_net(struct net *net)
502504
{

net/xfrm/espintcp.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ static void handle_nonesp(struct espintcp_ctx *ctx, struct sk_buff *skb,
2929

3030
static void handle_esp(struct sk_buff *skb, struct sock *sk)
3131
{
32+
struct tcp_skb_cb *tcp_cb = (struct tcp_skb_cb *)skb->cb;
33+
3234
skb_reset_transport_header(skb);
33-
memset(skb->cb, 0, sizeof(skb->cb));
35+
36+
/* restore IP CB, we need at least IP6CB->nhoff */
37+
memmove(skb->cb, &tcp_cb->header, sizeof(tcp_cb->header));
3438

3539
rcu_read_lock();
3640
skb->dev = dev_get_by_index_rcu(sock_net(sk), skb->skb_iif);

net/xfrm/xfrm_interface.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
303303
}
304304

305305
mtu = dst_mtu(dst);
306-
if (!skb->ignore_df && skb->len > mtu) {
306+
if (skb->len > mtu) {
307307
skb_dst_update_pmtu_no_confirm(skb, mtu);
308308

309309
if (skb->protocol == htons(ETH_P_IPV6)) {

net/xfrm/xfrm_state.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,8 @@ static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
10191019
*/
10201020
if (x->km.state == XFRM_STATE_VALID) {
10211021
if ((x->sel.family &&
1022-
!xfrm_selector_match(&x->sel, fl, x->sel.family)) ||
1022+
(x->sel.family != family ||
1023+
!xfrm_selector_match(&x->sel, fl, family))) ||
10231024
!security_xfrm_state_pol_flow_match(x, pol, fl))
10241025
return;
10251026

@@ -1032,7 +1033,9 @@ static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
10321033
*acq_in_progress = 1;
10331034
} else if (x->km.state == XFRM_STATE_ERROR ||
10341035
x->km.state == XFRM_STATE_EXPIRED) {
1035-
if (xfrm_selector_match(&x->sel, fl, x->sel.family) &&
1036+
if ((!x->sel.family ||
1037+
(x->sel.family == family &&
1038+
xfrm_selector_match(&x->sel, fl, family))) &&
10361039
security_xfrm_state_pol_flow_match(x, pol, fl))
10371040
*error = -ESRCH;
10381041
}
@@ -1072,7 +1075,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
10721075
tmpl->mode == x->props.mode &&
10731076
tmpl->id.proto == x->id.proto &&
10741077
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
1075-
xfrm_state_look_at(pol, x, fl, encap_family,
1078+
xfrm_state_look_at(pol, x, fl, family,
10761079
&best, &acquire_in_progress, &error);
10771080
}
10781081
if (best || acquire_in_progress)
@@ -1089,7 +1092,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
10891092
tmpl->mode == x->props.mode &&
10901093
tmpl->id.proto == x->id.proto &&
10911094
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
1092-
xfrm_state_look_at(pol, x, fl, encap_family,
1095+
xfrm_state_look_at(pol, x, fl, family,
10931096
&best, &acquire_in_progress, &error);
10941097
}
10951098

@@ -1441,6 +1444,30 @@ int xfrm_state_add(struct xfrm_state *x)
14411444
EXPORT_SYMBOL(xfrm_state_add);
14421445

14431446
#ifdef CONFIG_XFRM_MIGRATE
1447+
static inline int clone_security(struct xfrm_state *x, struct xfrm_sec_ctx *security)
1448+
{
1449+
struct xfrm_user_sec_ctx *uctx;
1450+
int size = sizeof(*uctx) + security->ctx_len;
1451+
int err;
1452+
1453+
uctx = kmalloc(size, GFP_KERNEL);
1454+
if (!uctx)
1455+
return -ENOMEM;
1456+
1457+
uctx->exttype = XFRMA_SEC_CTX;
1458+
uctx->len = size;
1459+
uctx->ctx_doi = security->ctx_doi;
1460+
uctx->ctx_alg = security->ctx_alg;
1461+
uctx->ctx_len = security->ctx_len;
1462+
memcpy(uctx + 1, security->ctx_str, security->ctx_len);
1463+
err = security_xfrm_state_alloc(x, uctx);
1464+
kfree(uctx);
1465+
if (err)
1466+
return err;
1467+
1468+
return 0;
1469+
}
1470+
14441471
static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
14451472
struct xfrm_encap_tmpl *encap)
14461473
{
@@ -1497,6 +1524,10 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
14971524
goto error;
14981525
}
14991526

1527+
if (orig->security)
1528+
if (clone_security(x, orig->security))
1529+
goto error;
1530+
15001531
if (orig->coaddr) {
15011532
x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr),
15021533
GFP_KERNEL);
@@ -1510,6 +1541,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
15101541
}
15111542

15121543
memcpy(&x->mark, &orig->mark, sizeof(x->mark));
1544+
memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
15131545

15141546
if (xfrm_init_state(x) < 0)
15151547
goto error;
@@ -1521,7 +1553,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
15211553
x->tfcpad = orig->tfcpad;
15221554
x->replay_maxdiff = orig->replay_maxdiff;
15231555
x->replay_maxage = orig->replay_maxage;
1524-
x->curlft.add_time = orig->curlft.add_time;
1556+
memcpy(&x->curlft, &orig->curlft, sizeof(x->curlft));
15251557
x->km.state = orig->km.state;
15261558
x->km.seq = orig->km.seq;
15271559
x->replay = orig->replay;

0 commit comments

Comments
 (0)