Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2015-10-22 1) Fix IPsec pre-encap fragmentation for GSO packets. From Herbert Xu. 2) Fix some header checks in _decode_session6. We skip the header informations if the data pointer points already behind the header in question for some protocols. This is because we call pskb_may_pull with a negative value converted to unsigened int from pskb_may_pull in this case. Skipping the header informations can lead to incorrect policy lookups. From Mathias Krause. 3) Allow to change the replay threshold and expiry timer of a state without having to set other attributes like replay counter and byte lifetime. Changing these other attributes may break the SA. From Michael Rossberg. 4) Fix pmtu discovery for local generated packets. We may fail dispatch to the inner address family. As a reault, the local error handler is not called and the mtu value is not reported back to userspace. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
199c655069
|
@ -30,6 +30,8 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
|
|||
|
||||
mtu = dst_mtu(skb_dst(skb));
|
||||
if (skb->len > mtu) {
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
|
||||
if (skb->sk)
|
||||
xfrm_local_error(skb, mtu);
|
||||
else
|
||||
|
|
|
@ -79,6 +79,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
|
|||
|
||||
if (!skb->ignore_df && skb->len > mtu) {
|
||||
skb->dev = dst->dev;
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
|
||||
if (xfrm6_local_dontfrag(skb))
|
||||
xfrm6_local_rxpmtu(skb, mtu);
|
||||
|
@ -136,6 +137,7 @@ static int __xfrm6_output(struct sock *sk, struct sk_buff *skb)
|
|||
struct dst_entry *dst = skb_dst(skb);
|
||||
struct xfrm_state *x = dst->xfrm;
|
||||
int mtu;
|
||||
bool toobig;
|
||||
|
||||
#ifdef CONFIG_NETFILTER
|
||||
if (!x) {
|
||||
|
@ -144,25 +146,29 @@ static int __xfrm6_output(struct sock *sk, struct sk_buff *skb)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (x->props.mode != XFRM_MODE_TUNNEL)
|
||||
goto skip_frag;
|
||||
|
||||
if (skb->protocol == htons(ETH_P_IPV6))
|
||||
mtu = ip6_skb_dst_mtu(skb);
|
||||
else
|
||||
mtu = dst_mtu(skb_dst(skb));
|
||||
|
||||
if (skb->len > mtu && xfrm6_local_dontfrag(skb)) {
|
||||
toobig = skb->len > mtu && !skb_is_gso(skb);
|
||||
|
||||
if (toobig && xfrm6_local_dontfrag(skb)) {
|
||||
xfrm6_local_rxpmtu(skb, mtu);
|
||||
return -EMSGSIZE;
|
||||
} else if (!skb->ignore_df && skb->len > mtu && skb->sk) {
|
||||
} else if (!skb->ignore_df && toobig && skb->sk) {
|
||||
xfrm_local_error(skb, mtu);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
if (x->props.mode == XFRM_MODE_TUNNEL &&
|
||||
((skb->len > mtu && !skb_is_gso(skb)) ||
|
||||
dst_allfrag(skb_dst(skb)))) {
|
||||
if (toobig || dst_allfrag(skb_dst(skb)))
|
||||
return ip6_fragment(sk, skb,
|
||||
x->outer_mode->afinfo->output_finish);
|
||||
}
|
||||
|
||||
skip_frag:
|
||||
return x->outer_mode->afinfo->output_finish(sk, skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
|
|||
return;
|
||||
|
||||
case IPPROTO_ICMPV6:
|
||||
if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
|
||||
if (!onlyproto && (nh + offset + 2 < skb->data ||
|
||||
pskb_may_pull(skb, nh + offset + 2 - skb->data))) {
|
||||
u8 *icmp;
|
||||
|
||||
nh = skb_network_header(skb);
|
||||
|
@ -193,7 +194,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
|
|||
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
||||
case IPPROTO_MH:
|
||||
offset += ipv6_optlen(exthdr);
|
||||
if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
|
||||
if (!onlyproto && (nh + offset + 3 < skb->data ||
|
||||
pskb_may_pull(skb, nh + offset + 3 - skb->data))) {
|
||||
struct ip6_mh *mh;
|
||||
|
||||
nh = skb_network_header(skb);
|
||||
|
|
|
@ -1928,8 +1928,10 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
struct nlattr *rp = attrs[XFRMA_REPLAY_VAL];
|
||||
struct nlattr *re = attrs[XFRMA_REPLAY_ESN_VAL];
|
||||
struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
|
||||
struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
|
||||
struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
|
||||
|
||||
if (!lt && !rp && !re)
|
||||
if (!lt && !rp && !re && !et && !rt)
|
||||
return err;
|
||||
|
||||
/* pedantic mode - thou shalt sayeth replaceth */
|
||||
|
|
Загрузка…
Ссылка в новой задаче