aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-17 06:29:28 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-17 06:29:28 -0400
commit6700c2709c08d74ae2c3c29b84a30da012dbc7f1 (patch)
tree1d44f300ec3cf5f9845fba7a25491e33d666426f /net
parent02f3d4ce9e81434a365f4643020b0402f6fe3332 (diff)
net: Pass optional SKB and SK arguments to dst_ops->{update_pmtu,redirect}()
This will be used so that we can compose a full flow key. Even though we have a route in this context, we need more. In the future the routes will be without destination address, source address, etc. keying. One ipv4 route will cover entire subnets, etc. In this environment we have to have a way to possess persistent storage for redirects and PMTU information. This persistent storage will exist in the FIB tables, and that's why we'll need to be able to rebuild a full lookup flow key here. Using that flow key will do a fib_lookup() and create/update the persistent entry. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_netfilter.c6
-rw-r--r--net/dccp/ipv4.c2
-rw-r--r--net/dccp/ipv6.c2
-rw-r--r--net/decnet/dn_route.c12
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/ip_gre.c2
-rw-r--r--net/ipv4/ipip.c2
-rw-r--r--net/ipv4/route.c21
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/xfrm4_policy.c10
-rw-r--r--net/ipv6/inet6_connection_sock.c2
-rw-r--r--net/ipv6/ip6_tunnel.c6
-rw-r--r--net/ipv6/route.c21
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/ipv6/xfrm6_policy.c10
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c4
-rw-r--r--net/sctp/input.c2
-rw-r--r--net/sctp/transport.c2
19 files changed, 66 insertions, 46 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 81f76c402cf2..68e8f364bbf8 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -111,11 +111,13 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb)
111 pppoe_proto(skb) == htons(PPP_IPV6) && \ 111 pppoe_proto(skb) == htons(PPP_IPV6) && \
112 brnf_filter_pppoe_tagged) 112 brnf_filter_pppoe_tagged)
113 113
114static void fake_update_pmtu(struct dst_entry *dst, u32 mtu) 114static void fake_update_pmtu(struct dst_entry *dst, struct sock *sk,
115 struct sk_buff *skb, u32 mtu)
115{ 116{
116} 117}
117 118
118static void fake_redirect(struct dst_entry *dst, struct sk_buff *skb) 119static void fake_redirect(struct dst_entry *dst, struct sock *sk,
120 struct sk_buff *skb)
119{ 121{
120} 122}
121 123
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 683902fcc8ed..ab4f44c9bb21 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -193,7 +193,7 @@ static void dccp_do_redirect(struct sk_buff *skb, struct sock *sk)
193 struct dst_entry *dst = __sk_dst_check(sk, 0); 193 struct dst_entry *dst = __sk_dst_check(sk, 0);
194 194
195 if (dst) 195 if (dst)
196 dst->ops->redirect(dst, skb); 196 dst->ops->redirect(dst, sk, skb);
197} 197}
198 198
199/* 199/*
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 3ee0342e1cec..56840b249f3b 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -134,7 +134,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
134 struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); 134 struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
135 135
136 if (dst) 136 if (dst)
137 dst->ops->redirect(dst, skb); 137 dst->ops->redirect(dst, sk, skb);
138 } 138 }
139 139
140 if (type == ICMPV6_PKT_TOOBIG) { 140 if (type == ICMPV6_PKT_TOOBIG) {
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index e9c4e2e864c6..47de90d8fe94 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -117,8 +117,10 @@ static void dn_dst_destroy(struct dst_entry *);
117static void dn_dst_ifdown(struct dst_entry *, struct net_device *dev, int how); 117static void dn_dst_ifdown(struct dst_entry *, struct net_device *dev, int how);
118static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); 118static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
119static void dn_dst_link_failure(struct sk_buff *); 119static void dn_dst_link_failure(struct sk_buff *);
120static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); 120static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk,
121static void dn_dst_redirect(struct dst_entry *dst, struct sk_buff *skb); 121 struct sk_buff *skb , u32 mtu);
122static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk,
123 struct sk_buff *skb);
122static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, 124static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst,
123 struct sk_buff *skb, 125 struct sk_buff *skb,
124 const void *daddr); 126 const void *daddr);
@@ -266,7 +268,8 @@ static int dn_dst_gc(struct dst_ops *ops)
266 * We update both the mtu and the advertised mss (i.e. the segment size we 268 * We update both the mtu and the advertised mss (i.e. the segment size we
267 * advertise to the other end). 269 * advertise to the other end).
268 */ 270 */
269static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) 271static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk,
272 struct sk_buff *skb, u32 mtu)
270{ 273{
271 struct dn_route *rt = (struct dn_route *) dst; 274 struct dn_route *rt = (struct dn_route *) dst;
272 struct neighbour *n = rt->n; 275 struct neighbour *n = rt->n;
@@ -294,7 +297,8 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
294 } 297 }
295} 298}
296 299
297static void dn_dst_redirect(struct dst_entry *dst, struct sk_buff *skb) 300static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk,
301 struct sk_buff *skb)
298{ 302{
299} 303}
300 304
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 200d21809379..3ea465286a39 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -840,7 +840,7 @@ struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu)
840 if (!dst) 840 if (!dst)
841 goto out; 841 goto out;
842 } 842 }
843 dst->ops->update_pmtu(dst, mtu); 843 dst->ops->update_pmtu(dst, sk, NULL, mtu);
844 844
845 dst = __sk_dst_check(sk, 0); 845 dst = __sk_dst_check(sk, 0);
846 if (!dst) 846 if (!dst)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 0c3123566d76..42c44b1403c9 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -833,7 +833,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
833 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; 833 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
834 834
835 if (skb_dst(skb)) 835 if (skb_dst(skb))
836 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 836 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
837 837
838 if (skb->protocol == htons(ETH_P_IP)) { 838 if (skb->protocol == htons(ETH_P_IP)) {
839 df |= (old_iph->frag_off&htons(IP_DF)); 839 df |= (old_iph->frag_off&htons(IP_DF));
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index c2d0e6d8baaf..2c2c35bace76 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -519,7 +519,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
519 } 519 }
520 520
521 if (skb_dst(skb)) 521 if (skb_dst(skb))
522 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 522 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
523 523
524 if ((old_iph->frag_off & htons(IP_DF)) && 524 if ((old_iph->frag_off & htons(IP_DF)) &&
525 mtu < ntohs(old_iph->tot_len)) { 525 mtu < ntohs(old_iph->tot_len)) {
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index aad21819316d..b35d3bfc66cd 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -148,8 +148,10 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst);
148static void ipv4_dst_destroy(struct dst_entry *dst); 148static void ipv4_dst_destroy(struct dst_entry *dst);
149static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); 149static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
150static void ipv4_link_failure(struct sk_buff *skb); 150static void ipv4_link_failure(struct sk_buff *skb);
151static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu); 151static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
152static void ip_do_redirect(struct dst_entry *dst, struct sk_buff *skb); 152 struct sk_buff *skb, u32 mtu);
153static void ip_do_redirect(struct dst_entry *dst, struct sock *sk,
154 struct sk_buff *skb);
153static int rt_garbage_collect(struct dst_ops *ops); 155static int rt_garbage_collect(struct dst_ops *ops);
154 156
155static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, 157static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
@@ -1273,7 +1275,7 @@ static void rt_del(unsigned int hash, struct rtable *rt)
1273 spin_unlock_bh(rt_hash_lock_addr(hash)); 1275 spin_unlock_bh(rt_hash_lock_addr(hash));
1274} 1276}
1275 1277
1276static void ip_do_redirect(struct dst_entry *dst, struct sk_buff *skb) 1278static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb)
1277{ 1279{
1278 __be32 new_gw = icmp_hdr(skb)->un.gateway; 1280 __be32 new_gw = icmp_hdr(skb)->un.gateway;
1279 __be32 old_gw = ip_hdr(skb)->saddr; 1281 __be32 old_gw = ip_hdr(skb)->saddr;
@@ -1506,7 +1508,8 @@ out: kfree_skb(skb);
1506 return 0; 1508 return 0;
1507} 1509}
1508 1510
1509static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) 1511static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
1512 struct sk_buff *skb, u32 mtu)
1510{ 1513{
1511 struct rtable *rt = (struct rtable *) dst; 1514 struct rtable *rt = (struct rtable *) dst;
1512 1515
@@ -1531,7 +1534,7 @@ void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
1531 iph->daddr, iph->saddr, 0, 0); 1534 iph->daddr, iph->saddr, 0, 0);
1532 rt = __ip_route_output_key(net, &fl4); 1535 rt = __ip_route_output_key(net, &fl4);
1533 if (!IS_ERR(rt)) { 1536 if (!IS_ERR(rt)) {
1534 ip_rt_update_pmtu(&rt->dst, mtu); 1537 ip_rt_update_pmtu(&rt->dst, NULL, skb, mtu);
1535 ip_rt_put(rt); 1538 ip_rt_put(rt);
1536 } 1539 }
1537} 1540}
@@ -1559,7 +1562,7 @@ void ipv4_redirect(struct sk_buff *skb, struct net *net,
1559 protocol, flow_flags, iph->daddr, iph->saddr, 0, 0); 1562 protocol, flow_flags, iph->daddr, iph->saddr, 0, 0);
1560 rt = __ip_route_output_key(net, &fl4); 1563 rt = __ip_route_output_key(net, &fl4);
1561 if (!IS_ERR(rt)) { 1564 if (!IS_ERR(rt)) {
1562 ip_do_redirect(&rt->dst, skb); 1565 ip_do_redirect(&rt->dst, NULL, skb);
1563 ip_rt_put(rt); 1566 ip_rt_put(rt);
1564 } 1567 }
1565} 1568}
@@ -2587,11 +2590,13 @@ static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst)
2587 return mtu ? : dst->dev->mtu; 2590 return mtu ? : dst->dev->mtu;
2588} 2591}
2589 2592
2590static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) 2593static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
2594 struct sk_buff *skb, u32 mtu)
2591{ 2595{
2592} 2596}
2593 2597
2594static void ipv4_rt_blackhole_redirect(struct dst_entry *dst, struct sk_buff *skb) 2598static void ipv4_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
2599 struct sk_buff *skb)
2595{ 2600{
2596} 2601}
2597 2602
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index b8e7e0595407..d9caf5c07aae 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -319,7 +319,7 @@ static void do_redirect(struct sk_buff *skb, struct sock *sk)
319 struct dst_entry *dst = __sk_dst_check(sk, 0); 319 struct dst_entry *dst = __sk_dst_check(sk, 0);
320 320
321 if (dst) 321 if (dst)
322 dst->ops->redirect(dst, skb); 322 dst->ops->redirect(dst, sk, skb);
323} 323}
324 324
325/* 325/*
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 737131cef375..fcf7678bc009 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -194,20 +194,22 @@ static inline int xfrm4_garbage_collect(struct dst_ops *ops)
194 return (dst_entries_get_slow(ops) > ops->gc_thresh * 2); 194 return (dst_entries_get_slow(ops) > ops->gc_thresh * 2);
195} 195}
196 196
197static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) 197static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk,
198 struct sk_buff *skb, u32 mtu)
198{ 199{
199 struct xfrm_dst *xdst = (struct xfrm_dst *)dst; 200 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
200 struct dst_entry *path = xdst->route; 201 struct dst_entry *path = xdst->route;
201 202
202 path->ops->update_pmtu(path, mtu); 203 path->ops->update_pmtu(path, sk, skb, mtu);
203} 204}
204 205
205static void xfrm4_redirect(struct dst_entry *dst, struct sk_buff *skb) 206static void xfrm4_redirect(struct dst_entry *dst, struct sock *sk,
207 struct sk_buff *skb)
206{ 208{
207 struct xfrm_dst *xdst = (struct xfrm_dst *)dst; 209 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
208 struct dst_entry *path = xdst->route; 210 struct dst_entry *path = xdst->route;
209 211
210 path->ops->redirect(path, skb); 212 path->ops->redirect(path, sk, skb);
211} 213}
212 214
213static void xfrm4_dst_destroy(struct dst_entry *dst) 215static void xfrm4_dst_destroy(struct dst_entry *dst)
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 62539a4b2dc7..4a0c4d2d8b05 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -269,7 +269,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
269 269
270 if (IS_ERR(dst)) 270 if (IS_ERR(dst))
271 return NULL; 271 return NULL;
272 dst->ops->update_pmtu(dst, mtu); 272 dst->ops->update_pmtu(dst, sk, NULL, mtu);
273 273
274 return inet6_csk_route_socket(sk); 274 return inet6_csk_route_socket(sk);
275} 275}
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 61d106597296..db3284667968 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -609,10 +609,10 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
609 if (rel_info > dst_mtu(skb_dst(skb2))) 609 if (rel_info > dst_mtu(skb_dst(skb2)))
610 goto out; 610 goto out;
611 611
612 skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), rel_info); 612 skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), NULL, skb2, rel_info);
613 } 613 }
614 if (rel_type == ICMP_REDIRECT) 614 if (rel_type == ICMP_REDIRECT)
615 skb_dst(skb2)->ops->redirect(skb_dst(skb2), skb2); 615 skb_dst(skb2)->ops->redirect(skb_dst(skb2), NULL, skb2);
616 616
617 icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); 617 icmp_send(skb2, rel_type, rel_code, htonl(rel_info));
618 618
@@ -952,7 +952,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
952 if (mtu < IPV6_MIN_MTU) 952 if (mtu < IPV6_MIN_MTU)
953 mtu = IPV6_MIN_MTU; 953 mtu = IPV6_MIN_MTU;
954 if (skb_dst(skb)) 954 if (skb_dst(skb))
955 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 955 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
956 if (skb->len > mtu) { 956 if (skb->len > mtu) {
957 *pmtu = mtu; 957 *pmtu = mtu;
958 err = -EMSGSIZE; 958 err = -EMSGSIZE;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 2a4c8d48977f..31af1ed6c1dc 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -78,8 +78,10 @@ static int ip6_dst_gc(struct dst_ops *ops);
78static int ip6_pkt_discard(struct sk_buff *skb); 78static int ip6_pkt_discard(struct sk_buff *skb);
79static int ip6_pkt_discard_out(struct sk_buff *skb); 79static int ip6_pkt_discard_out(struct sk_buff *skb);
80static void ip6_link_failure(struct sk_buff *skb); 80static void ip6_link_failure(struct sk_buff *skb);
81static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu); 81static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
82static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb); 82 struct sk_buff *skb, u32 mtu);
83static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk,
84 struct sk_buff *skb);
83 85
84#ifdef CONFIG_IPV6_ROUTE_INFO 86#ifdef CONFIG_IPV6_ROUTE_INFO
85static struct rt6_info *rt6_add_route_info(struct net *net, 87static struct rt6_info *rt6_add_route_info(struct net *net,
@@ -187,11 +189,13 @@ static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst)
187 return mtu ? : dst->dev->mtu; 189 return mtu ? : dst->dev->mtu;
188} 190}
189 191
190static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) 192static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
193 struct sk_buff *skb, u32 mtu)
191{ 194{
192} 195}
193 196
194static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sk_buff *skb) 197static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
198 struct sk_buff *skb)
195{ 199{
196} 200}
197 201
@@ -1071,7 +1075,8 @@ static void ip6_link_failure(struct sk_buff *skb)
1071 } 1075 }
1072} 1076}
1073 1077
1074static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) 1078static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
1079 struct sk_buff *skb, u32 mtu)
1075{ 1080{
1076 struct rt6_info *rt6 = (struct rt6_info*)dst; 1081 struct rt6_info *rt6 = (struct rt6_info*)dst;
1077 1082
@@ -1108,7 +1113,7 @@ void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
1108 1113
1109 dst = ip6_route_output(net, NULL, &fl6); 1114 dst = ip6_route_output(net, NULL, &fl6);
1110 if (!dst->error) 1115 if (!dst->error)
1111 ip6_rt_update_pmtu(dst, ntohl(mtu)); 1116 ip6_rt_update_pmtu(dst, NULL, skb, ntohl(mtu));
1112 dst_release(dst); 1117 dst_release(dst);
1113} 1118}
1114EXPORT_SYMBOL_GPL(ip6_update_pmtu); 1119EXPORT_SYMBOL_GPL(ip6_update_pmtu);
@@ -1136,7 +1141,7 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
1136 1141
1137 dst = ip6_route_output(net, NULL, &fl6); 1142 dst = ip6_route_output(net, NULL, &fl6);
1138 if (!dst->error) 1143 if (!dst->error)
1139 rt6_do_redirect(dst, skb); 1144 rt6_do_redirect(dst, NULL, skb);
1140 dst_release(dst); 1145 dst_release(dst);
1141} 1146}
1142EXPORT_SYMBOL_GPL(ip6_redirect); 1147EXPORT_SYMBOL_GPL(ip6_redirect);
@@ -1639,7 +1644,7 @@ static int ip6_route_del(struct fib6_config *cfg)
1639 return err; 1644 return err;
1640} 1645}
1641 1646
1642static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb) 1647static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb)
1643{ 1648{
1644 struct net *net = dev_net(skb->dev); 1649 struct net *net = dev_net(skb->dev);
1645 struct netevent_redirect netevent; 1650 struct netevent_redirect netevent;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index fbf1622fdeef..3bd1bfc01f85 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -807,7 +807,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
807 } 807 }
808 808
809 if (tunnel->parms.iph.daddr && skb_dst(skb)) 809 if (tunnel->parms.iph.daddr && skb_dst(skb))
810 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 810 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
811 811
812 if (skb->len > mtu) { 812 if (skb->len > mtu) {
813 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 813 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index ecdf241cad02..c9dabdd832d7 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -367,7 +367,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
367 struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); 367 struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
368 368
369 if (dst) 369 if (dst)
370 dst->ops->redirect(dst,skb); 370 dst->ops->redirect(dst, sk, skb);
371 } 371 }
372 372
373 if (type == ICMPV6_PKT_TOOBIG) { 373 if (type == ICMPV6_PKT_TOOBIG) {
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index f5a9cb8257b9..ef39812107b1 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -207,20 +207,22 @@ static inline int xfrm6_garbage_collect(struct dst_ops *ops)
207 return dst_entries_get_fast(ops) > ops->gc_thresh * 2; 207 return dst_entries_get_fast(ops) > ops->gc_thresh * 2;
208} 208}
209 209
210static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) 210static void xfrm6_update_pmtu(struct dst_entry *dst, struct sock *sk,
211 struct sk_buff *skb, u32 mtu)
211{ 212{
212 struct xfrm_dst *xdst = (struct xfrm_dst *)dst; 213 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
213 struct dst_entry *path = xdst->route; 214 struct dst_entry *path = xdst->route;
214 215
215 path->ops->update_pmtu(path, mtu); 216 path->ops->update_pmtu(path, sk, skb, mtu);
216} 217}
217 218
218static void xfrm6_redirect(struct dst_entry *dst, struct sk_buff *skb) 219static void xfrm6_redirect(struct dst_entry *dst, struct sock *sk,
220 struct sk_buff *skb)
219{ 221{
220 struct xfrm_dst *xdst = (struct xfrm_dst *)dst; 222 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
221 struct dst_entry *path = xdst->route; 223 struct dst_entry *path = xdst->route;
222 224
223 path->ops->redirect(path, skb); 225 path->ops->redirect(path, sk, skb);
224} 226}
225 227
226static void xfrm6_dst_destroy(struct dst_entry *dst) 228static void xfrm6_dst_destroy(struct dst_entry *dst)
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 71d6ecb65926..65b616ae1716 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -797,7 +797,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
797 goto tx_error_put; 797 goto tx_error_put;
798 } 798 }
799 if (skb_dst(skb)) 799 if (skb_dst(skb))
800 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 800 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
801 801
802 df |= (old_iph->frag_off & htons(IP_DF)); 802 df |= (old_iph->frag_off & htons(IP_DF));
803 803
@@ -913,7 +913,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
913 goto tx_error_put; 913 goto tx_error_put;
914 } 914 }
915 if (skb_dst(skb)) 915 if (skb_dst(skb))
916 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 916 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
917 917
918 if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) && 918 if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) &&
919 !skb_is_gso(skb)) { 919 !skb_is_gso(skb)) {
diff --git a/net/sctp/input.c b/net/sctp/input.c
index a67bc31f49fd..c201b26879a1 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -432,7 +432,7 @@ void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t,
432 return; 432 return;
433 dst = sctp_transport_dst_check(t); 433 dst = sctp_transport_dst_check(t);
434 if (dst) 434 if (dst)
435 dst->ops->redirect(dst, skb); 435 dst->ops->redirect(dst, sk, skb);
436} 436}
437 437
438/* 438/*
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index e69e1a2175a4..a6b7ee9ce28a 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -249,7 +249,7 @@ void sctp_transport_update_pmtu(struct sock *sk, struct sctp_transport *t, u32 p
249 t->af_specific->get_dst(t, &t->saddr, &t->fl, sk); 249 t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
250 250
251 if (dst) { 251 if (dst) {
252 dst->ops->update_pmtu(dst, pmtu); 252 dst->ops->update_pmtu(dst, sk, NULL, pmtu);
253 253
254 dst = sctp_transport_dst_check(t); 254 dst = sctp_transport_dst_check(t);
255 if (!dst) 255 if (!dst)