summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-09-08 16:12:37 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-08 16:12:37 -0400
commit40e3012e6ea715e957347477a980145210735267 (patch)
tree492d68025341754ae2408917eb4466dd1c25a1b7 /net
parent9dd4aaef194e45d96c2d0b6232a9cbc5430ad789 (diff)
parent11d7a0bb95eaaba1741bb24a7c3c169c82f09c7b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== ipsec 2016-09-08 1) Fix a crash when xfrm_dump_sa returns an error. From Vegard Nossum. 2) Remove some incorrect WARN() on normal error handling. From Vegard Nossum. 3) Ignore socket policies when rebuilding hash tables, socket policies are not inserted into the hash tables. From Tobias Brunner. 4) Initialize and check tunnel pointers properly before we use it. From Alexey Kodanev. 5) Fix l3mdev oif setting on xfrm dst lookups. From David Ahern. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/xfrm4_policy.c2
-rw-r--r--net/ipv6/xfrm6_input.c1
-rw-r--r--net/ipv6/xfrm6_policy.c2
-rw-r--r--net/xfrm/xfrm_input.c14
-rw-r--r--net/xfrm/xfrm_policy.c4
-rw-r--r--net/xfrm/xfrm_user.c13
6 files changed, 18 insertions, 18 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index b644a23c3db0..41f5b504a782 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -29,7 +29,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
29 memset(fl4, 0, sizeof(*fl4)); 29 memset(fl4, 0, sizeof(*fl4));
30 fl4->daddr = daddr->a4; 30 fl4->daddr = daddr->a4;
31 fl4->flowi4_tos = tos; 31 fl4->flowi4_tos = tos;
32 fl4->flowi4_oif = oif; 32 fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif);
33 if (saddr) 33 if (saddr)
34 fl4->saddr = saddr->a4; 34 fl4->saddr = saddr->a4;
35 35
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 0eaab1fa6be5..00a2d40677d6 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -23,6 +23,7 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
23 23
24int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) 24int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
25{ 25{
26 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
26 XFRM_SPI_SKB_CB(skb)->family = AF_INET6; 27 XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
27 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); 28 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
28 return xfrm_input(skb, nexthdr, spi, 0); 29 return xfrm_input(skb, nexthdr, spi, 0);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 6cc97003e4a9..70a86adad875 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -36,7 +36,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
36 int err; 36 int err;
37 37
38 memset(&fl6, 0, sizeof(fl6)); 38 memset(&fl6, 0, sizeof(fl6));
39 fl6.flowi6_oif = oif; 39 fl6.flowi6_oif = l3mdev_master_ifindex_by_index(net, oif);
40 fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; 40 fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF;
41 memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); 41 memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
42 if (saddr) 42 if (saddr)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 1c4ad477ce93..6e3f0254d8a1 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -207,15 +207,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
207 family = XFRM_SPI_SKB_CB(skb)->family; 207 family = XFRM_SPI_SKB_CB(skb)->family;
208 208
209 /* if tunnel is present override skb->mark value with tunnel i_key */ 209 /* if tunnel is present override skb->mark value with tunnel i_key */
210 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) { 210 switch (family) {
211 switch (family) { 211 case AF_INET:
212 case AF_INET: 212 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
213 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); 213 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key);
214 break; 214 break;
215 case AF_INET6: 215 case AF_INET6:
216 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
216 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); 217 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key);
217 break; 218 break;
218 }
219 } 219 }
220 220
221 /* Allocate new secpath or COW existing one. */ 221 /* Allocate new secpath or COW existing one. */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b5e665b3cfb0..45f9cf97ea25 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -626,6 +626,10 @@ static void xfrm_hash_rebuild(struct work_struct *work)
626 626
627 /* re-insert all policies by order of creation */ 627 /* re-insert all policies by order of creation */
628 list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { 628 list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) {
629 if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) {
630 /* skip socket policies */
631 continue;
632 }
629 newpos = NULL; 633 newpos = NULL;
630 chain = policy_hash_bysel(net, &policy->selector, 634 chain = policy_hash_bysel(net, &policy->selector,
631 policy->family, 635 policy->family,
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index d516845e16e3..cb65d916a345 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -896,7 +896,8 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb)
896 struct sock *sk = cb->skb->sk; 896 struct sock *sk = cb->skb->sk;
897 struct net *net = sock_net(sk); 897 struct net *net = sock_net(sk);
898 898
899 xfrm_state_walk_done(walk, net); 899 if (cb->args[0])
900 xfrm_state_walk_done(walk, net);
900 return 0; 901 return 0;
901} 902}
902 903
@@ -921,8 +922,6 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
921 u8 proto = 0; 922 u8 proto = 0;
922 int err; 923 int err;
923 924
924 cb->args[0] = 1;
925
926 err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX, 925 err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX,
927 xfrma_policy); 926 xfrma_policy);
928 if (err < 0) 927 if (err < 0)
@@ -939,6 +938,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
939 proto = nla_get_u8(attrs[XFRMA_PROTO]); 938 proto = nla_get_u8(attrs[XFRMA_PROTO]);
940 939
941 xfrm_state_walk_init(walk, proto, filter); 940 xfrm_state_walk_init(walk, proto, filter);
941 cb->args[0] = 1;
942 } 942 }
943 943
944 (void) xfrm_state_walk(net, walk, dump_one_state, &info); 944 (void) xfrm_state_walk(net, walk, dump_one_state, &info);
@@ -2051,9 +2051,6 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
2051 if (up->hard) { 2051 if (up->hard) {
2052 xfrm_policy_delete(xp, p->dir); 2052 xfrm_policy_delete(xp, p->dir);
2053 xfrm_audit_policy_delete(xp, 1, true); 2053 xfrm_audit_policy_delete(xp, 1, true);
2054 } else {
2055 // reset the timers here?
2056 WARN(1, "Don't know what to do with soft policy expire\n");
2057 } 2054 }
2058 km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid); 2055 km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid);
2059 2056
@@ -2117,7 +2114,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
2117 2114
2118 err = verify_newpolicy_info(&ua->policy); 2115 err = verify_newpolicy_info(&ua->policy);
2119 if (err) 2116 if (err)
2120 goto bad_policy; 2117 goto free_state;
2121 2118
2122 /* build an XP */ 2119 /* build an XP */
2123 xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); 2120 xp = xfrm_policy_construct(net, &ua->policy, attrs, &err);
@@ -2149,8 +2146,6 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
2149 2146
2150 return 0; 2147 return 0;
2151 2148
2152bad_policy:
2153 WARN(1, "BAD policy passed\n");
2154free_state: 2149free_state:
2155 kfree(x); 2150 kfree(x);
2156nomem: 2151nomem: