aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5c618f20523e..28209b2d254d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1002,29 +1002,87 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
1002EXPORT_SYMBOL_GPL(ip6_dst_lookup); 1002EXPORT_SYMBOL_GPL(ip6_dst_lookup);
1003 1003
1004/** 1004/**
1005 * ip6_sk_dst_lookup - perform socket cached route lookup on flow 1005 * ip6_dst_lookup_flow - perform route lookup on flow with ipsec
1006 * @sk: socket which provides route info
1007 * @fl: flow to lookup
1008 * @final_dst: final destination address for ipsec lookup
1009 * @want_blackhole: IPSEC blackhole handling desired
1010 *
1011 * This function performs a route lookup on the given flow.
1012 *
1013 * It returns a valid dst pointer on success, or a pointer encoded
1014 * error code.
1015 */
1016struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi *fl,
1017 const struct in6_addr *final_dst,
1018 bool want_blackhole)
1019{
1020 struct dst_entry *dst = NULL;
1021 int err;
1022
1023 err = ip6_dst_lookup_tail(sk, &dst, fl);
1024 if (err)
1025 return ERR_PTR(err);
1026 if (final_dst)
1027 ipv6_addr_copy(&fl->fl6_dst, final_dst);
1028 if (want_blackhole) {
1029 err = __xfrm_lookup(sock_net(sk), &dst, fl, sk, XFRM_LOOKUP_WAIT);
1030 if (err == -EREMOTE)
1031 err = ip6_dst_blackhole(sk, &dst, fl);
1032 if (err)
1033 return ERR_PTR(err);
1034 } else {
1035 err = xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1036 if (err)
1037 return ERR_PTR(err);
1038 }
1039 return dst;
1040}
1041EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
1042
1043/**
1044 * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
1006 * @sk: socket which provides the dst cache and route info 1045 * @sk: socket which provides the dst cache and route info
1007 * @dst: pointer to dst_entry * for result
1008 * @fl: flow to lookup 1046 * @fl: flow to lookup
1047 * @final_dst: final destination address for ipsec lookup
1048 * @want_blackhole: IPSEC blackhole handling desired
1009 * 1049 *
1010 * This function performs a route lookup on the given flow with the 1050 * This function performs a route lookup on the given flow with the
1011 * possibility of using the cached route in the socket if it is valid. 1051 * possibility of using the cached route in the socket if it is valid.
1012 * It will take the socket dst lock when operating on the dst cache. 1052 * It will take the socket dst lock when operating on the dst cache.
1013 * As a result, this function can only be used in process context. 1053 * As a result, this function can only be used in process context.
1014 * 1054 *
1015 * It returns zero on success, or a standard errno code on error. 1055 * It returns a valid dst pointer on success, or a pointer encoded
1056 * error code.
1016 */ 1057 */
1017int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) 1058struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi *fl,
1059 const struct in6_addr *final_dst,
1060 bool want_blackhole)
1018{ 1061{
1019 *dst = NULL; 1062 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
1020 if (sk) { 1063 int err;
1021 *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
1022 *dst = ip6_sk_dst_check(sk, *dst, fl);
1023 }
1024 1064
1025 return ip6_dst_lookup_tail(sk, dst, fl); 1065 dst = ip6_sk_dst_check(sk, dst, fl);
1066
1067 err = ip6_dst_lookup_tail(sk, &dst, fl);
1068 if (err)
1069 return ERR_PTR(err);
1070 if (final_dst)
1071 ipv6_addr_copy(&fl->fl6_dst, final_dst);
1072 if (want_blackhole) {
1073 err = __xfrm_lookup(sock_net(sk), &dst, fl, sk, XFRM_LOOKUP_WAIT);
1074 if (err == -EREMOTE)
1075 err = ip6_dst_blackhole(sk, &dst, fl);
1076 if (err)
1077 return ERR_PTR(err);
1078 } else {
1079 err = xfrm_lookup(sock_net(sk), &dst, fl, sk, 0);
1080 if (err)
1081 return ERR_PTR(err);
1082 }
1083 return dst;
1026} 1084}
1027EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup); 1085EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
1028 1086
1029static inline int ip6_ufo_append_data(struct sock *sk, 1087static inline int ip6_ufo_append_data(struct sock *sk,
1030 int getfrag(void *from, char *to, int offset, int len, 1088 int getfrag(void *from, char *to, int offset, int len,