ipsec-2023-06-20
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH7ZpcWbFyOOp6OJbrB3Eaf9PW7cFAmSRfcsACgkQrB3Eaf9P W7cOew//Q2FYj4vOw3DNYN1NgLzDac6wS5YtBxXh9QSJXTBhx9yXW6/Y++AFrP/4 GfgfQvgIHcRLUZZkZiiILmpiq5QcaTDTrryz0/HnWe72/rv/vm2RcZ9amQD4g4/x U+HOwiDpE0uP0nHbfclvQe/AZARfrLLhjItOGYNGDtinlQpudnTJM4QR+cr8EtZF 8cNJ8YWylIlag+utaPMzYsaCgnTxt9vRzReQpdAgxHiyF7QD2FGfqZ5B+Re9CoSq kt/I6tNmKZ/SBGnRrCQNA0fMNMqMapGyMMqSVNUkpaVbc/ZvzO0GbtMGfT1sJ+rJ mGECTEqMbqxpLUpTKOtr3MVZ5ddIwezBzEop+AIG82MSbkIN+yYQw69pWkY6e5cY DFg709CQ+LrRVib/LUsJpnqnpS9CWD8Vi1uqFza8wivknaEu2FauSKQxIKQo9qux zmk377h7EzVF/asdtG7j1KdljyRaX5r5OnTF4fPVEHA4QF62ZxO2swQKy+EG9Fu/ eQvafxuCfEAgcn5GDRzgjrvSKfFGRXyxDncsc8T7HphiuPR5rFQt3x9DhfcMn4Ds vezC4cXa2HYyhFj52tZ8KJAbmhVJz87eBUoiM/aTOdGPRFmVExOnuY1RsIYPxcIz m4aOvIWEtFjpYkpzEXOB3/lq7gjfggz3zVloXAoaeonIvnzahgw= =co/J -----END PGP SIGNATURE----- Merge tag 'ipsec-2023-06-20' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec ipsec-2023-06-20
This commit is contained in:
commit
e438edaae2
@ -1054,6 +1054,7 @@ struct xfrm_offload {
|
|||||||
struct sec_path {
|
struct sec_path {
|
||||||
int len;
|
int len;
|
||||||
int olen;
|
int olen;
|
||||||
|
int verified_cnt;
|
||||||
|
|
||||||
struct xfrm_state *xvec[XFRM_MAX_DEPTH];
|
struct xfrm_state *xvec[XFRM_MAX_DEPTH];
|
||||||
struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
|
struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
|
||||||
|
@ -340,6 +340,9 @@ static int esp_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features_
|
|||||||
|
|
||||||
secpath_reset(skb);
|
secpath_reset(skb);
|
||||||
|
|
||||||
|
if (skb_needs_linearize(skb, skb->dev->features) &&
|
||||||
|
__skb_linearize(skb))
|
||||||
|
return -ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +164,7 @@ drop:
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(xfrm4_udp_encap_rcv);
|
||||||
|
|
||||||
int xfrm4_rcv(struct sk_buff *skb)
|
int xfrm4_rcv(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -374,6 +374,9 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features
|
|||||||
|
|
||||||
secpath_reset(skb);
|
secpath_reset(skb);
|
||||||
|
|
||||||
|
if (skb_needs_linearize(skb, skb->dev->features) &&
|
||||||
|
__skb_linearize(skb))
|
||||||
|
return -ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,9 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
|
|||||||
__be32 *udpdata32;
|
__be32 *udpdata32;
|
||||||
__u16 encap_type = up->encap_type;
|
__u16 encap_type = up->encap_type;
|
||||||
|
|
||||||
|
if (skb->protocol == htons(ETH_P_IP))
|
||||||
|
return xfrm4_udp_encap_rcv(sk, skb);
|
||||||
|
|
||||||
/* if this is not encapsulated socket, then just return now */
|
/* if this is not encapsulated socket, then just return now */
|
||||||
if (!encap_type)
|
if (!encap_type)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -131,6 +131,7 @@ struct sec_path *secpath_set(struct sk_buff *skb)
|
|||||||
memset(sp->ovec, 0, sizeof(sp->ovec));
|
memset(sp->ovec, 0, sizeof(sp->ovec));
|
||||||
sp->olen = 0;
|
sp->olen = 0;
|
||||||
sp->len = 0;
|
sp->len = 0;
|
||||||
|
sp->verified_cnt = 0;
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
@ -330,11 +331,10 @@ xfrm_inner_mode_encap_remove(struct xfrm_state *x,
|
|||||||
{
|
{
|
||||||
switch (x->props.mode) {
|
switch (x->props.mode) {
|
||||||
case XFRM_MODE_BEET:
|
case XFRM_MODE_BEET:
|
||||||
switch (XFRM_MODE_SKB_CB(skb)->protocol) {
|
switch (x->sel.family) {
|
||||||
case IPPROTO_IPIP:
|
case AF_INET:
|
||||||
case IPPROTO_BEETPH:
|
|
||||||
return xfrm4_remove_beet_encap(x, skb);
|
return xfrm4_remove_beet_encap(x, skb);
|
||||||
case IPPROTO_IPV6:
|
case AF_INET6:
|
||||||
return xfrm6_remove_beet_encap(x, skb);
|
return xfrm6_remove_beet_encap(x, skb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -310,6 +310,52 @@ static void xfrmi_scrub_packet(struct sk_buff *skb, bool xnet)
|
|||||||
skb->mark = 0;
|
skb->mark = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xfrmi_input(struct sk_buff *skb, int nexthdr, __be32 spi,
|
||||||
|
int encap_type, unsigned short family)
|
||||||
|
{
|
||||||
|
struct sec_path *sp;
|
||||||
|
|
||||||
|
sp = skb_sec_path(skb);
|
||||||
|
if (sp && (sp->len || sp->olen) &&
|
||||||
|
!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family))
|
||||||
|
goto discard;
|
||||||
|
|
||||||
|
XFRM_SPI_SKB_CB(skb)->family = family;
|
||||||
|
if (family == AF_INET) {
|
||||||
|
XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
|
||||||
|
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
|
||||||
|
} else {
|
||||||
|
XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
|
||||||
|
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xfrm_input(skb, nexthdr, spi, encap_type);
|
||||||
|
discard:
|
||||||
|
kfree_skb(skb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xfrmi4_rcv(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return xfrmi_input(skb, ip_hdr(skb)->protocol, 0, 0, AF_INET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xfrmi6_rcv(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return xfrmi_input(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
|
||||||
|
0, 0, AF_INET6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xfrmi4_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
|
||||||
|
{
|
||||||
|
return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xfrmi6_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
|
||||||
|
{
|
||||||
|
return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET6);
|
||||||
|
}
|
||||||
|
|
||||||
static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
|
static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
|
||||||
{
|
{
|
||||||
const struct xfrm_mode *inner_mode;
|
const struct xfrm_mode *inner_mode;
|
||||||
@ -945,8 +991,8 @@ static struct pernet_operations xfrmi_net_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct xfrm6_protocol xfrmi_esp6_protocol __read_mostly = {
|
static struct xfrm6_protocol xfrmi_esp6_protocol __read_mostly = {
|
||||||
.handler = xfrm6_rcv,
|
.handler = xfrmi6_rcv,
|
||||||
.input_handler = xfrm_input,
|
.input_handler = xfrmi6_input,
|
||||||
.cb_handler = xfrmi_rcv_cb,
|
.cb_handler = xfrmi_rcv_cb,
|
||||||
.err_handler = xfrmi6_err,
|
.err_handler = xfrmi6_err,
|
||||||
.priority = 10,
|
.priority = 10,
|
||||||
@ -996,8 +1042,8 @@ static struct xfrm6_tunnel xfrmi_ip6ip_handler __read_mostly = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct xfrm4_protocol xfrmi_esp4_protocol __read_mostly = {
|
static struct xfrm4_protocol xfrmi_esp4_protocol __read_mostly = {
|
||||||
.handler = xfrm4_rcv,
|
.handler = xfrmi4_rcv,
|
||||||
.input_handler = xfrm_input,
|
.input_handler = xfrmi4_input,
|
||||||
.cb_handler = xfrmi_rcv_cb,
|
.cb_handler = xfrmi_rcv_cb,
|
||||||
.err_handler = xfrmi4_err,
|
.err_handler = xfrmi4_err,
|
||||||
.priority = 10,
|
.priority = 10,
|
||||||
|
@ -1831,6 +1831,7 @@ again:
|
|||||||
|
|
||||||
__xfrm_policy_unlink(pol, dir);
|
__xfrm_policy_unlink(pol, dir);
|
||||||
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
||||||
|
xfrm_dev_policy_delete(pol);
|
||||||
cnt++;
|
cnt++;
|
||||||
xfrm_audit_policy_delete(pol, 1, task_valid);
|
xfrm_audit_policy_delete(pol, 1, task_valid);
|
||||||
xfrm_policy_kill(pol);
|
xfrm_policy_kill(pol);
|
||||||
@ -1869,6 +1870,7 @@ again:
|
|||||||
|
|
||||||
__xfrm_policy_unlink(pol, dir);
|
__xfrm_policy_unlink(pol, dir);
|
||||||
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
||||||
|
xfrm_dev_policy_delete(pol);
|
||||||
cnt++;
|
cnt++;
|
||||||
xfrm_audit_policy_delete(pol, 1, task_valid);
|
xfrm_audit_policy_delete(pol, 1, task_valid);
|
||||||
xfrm_policy_kill(pol);
|
xfrm_policy_kill(pol);
|
||||||
@ -3349,6 +3351,13 @@ xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int star
|
|||||||
if (xfrm_state_ok(tmpl, sp->xvec[idx], family, if_id))
|
if (xfrm_state_ok(tmpl, sp->xvec[idx], family, if_id))
|
||||||
return ++idx;
|
return ++idx;
|
||||||
if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) {
|
if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) {
|
||||||
|
if (idx < sp->verified_cnt) {
|
||||||
|
/* Secpath entry previously verified, consider optional and
|
||||||
|
* continue searching
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (start == -1)
|
if (start == -1)
|
||||||
start = -2-idx;
|
start = -2-idx;
|
||||||
break;
|
break;
|
||||||
@ -3723,6 +3732,9 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
|||||||
* Order is _important_. Later we will implement
|
* Order is _important_. Later we will implement
|
||||||
* some barriers, but at the moment barriers
|
* some barriers, but at the moment barriers
|
||||||
* are implied between each two transformations.
|
* are implied between each two transformations.
|
||||||
|
* Upon success, marks secpath entries as having been
|
||||||
|
* verified to allow them to be skipped in future policy
|
||||||
|
* checks (e.g. nested tunnels).
|
||||||
*/
|
*/
|
||||||
for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
|
for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
|
||||||
k = xfrm_policy_ok(tpp[i], sp, k, family, if_id);
|
k = xfrm_policy_ok(tpp[i], sp, k, family, if_id);
|
||||||
@ -3741,6 +3753,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
xfrm_pols_put(pols, npols);
|
xfrm_pols_put(pols, npols);
|
||||||
|
sp->verified_cnt = k;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
|
XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
|
||||||
|
Loading…
Reference in New Issue
Block a user