aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-12 16:22:43 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-12 18:08:54 -0500
commit4c9483b2fb5d2548c3cc1fe03cdd4484ceeb5d1c (patch)
treec29c8070012cffb38fe249cf528589a675f622b1 /net/ipv6/ip6_output.c
parent9cce96df5b76691712dba22e83ff5efe900361e1 (diff)
ipv6: Convert to use flowi6 where applicable.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c90
1 files changed, 45 insertions, 45 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3d0f2ac868a7..18208876aa8a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -174,15 +174,15 @@ int ip6_output(struct sk_buff *skb)
174 * xmit an sk_buff (used by TCP, SCTP and DCCP) 174 * xmit an sk_buff (used by TCP, SCTP and DCCP)
175 */ 175 */
176 176
177int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 177int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
178 struct ipv6_txoptions *opt) 178 struct ipv6_txoptions *opt)
179{ 179{
180 struct net *net = sock_net(sk); 180 struct net *net = sock_net(sk);
181 struct ipv6_pinfo *np = inet6_sk(sk); 181 struct ipv6_pinfo *np = inet6_sk(sk);
182 struct in6_addr *first_hop = &fl->fl6_dst; 182 struct in6_addr *first_hop = &fl6->daddr;
183 struct dst_entry *dst = skb_dst(skb); 183 struct dst_entry *dst = skb_dst(skb);
184 struct ipv6hdr *hdr; 184 struct ipv6hdr *hdr;
185 u8 proto = fl->flowi_proto; 185 u8 proto = fl6->flowi6_proto;
186 int seg_len = skb->len; 186 int seg_len = skb->len;
187 int hlimit = -1; 187 int hlimit = -1;
188 int tclass = 0; 188 int tclass = 0;
@@ -230,13 +230,13 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
230 if (hlimit < 0) 230 if (hlimit < 0)
231 hlimit = ip6_dst_hoplimit(dst); 231 hlimit = ip6_dst_hoplimit(dst);
232 232
233 *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; 233 *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;
234 234
235 hdr->payload_len = htons(seg_len); 235 hdr->payload_len = htons(seg_len);
236 hdr->nexthdr = proto; 236 hdr->nexthdr = proto;
237 hdr->hop_limit = hlimit; 237 hdr->hop_limit = hlimit;
238 238
239 ipv6_addr_copy(&hdr->saddr, &fl->fl6_src); 239 ipv6_addr_copy(&hdr->saddr, &fl6->saddr);
240 ipv6_addr_copy(&hdr->daddr, first_hop); 240 ipv6_addr_copy(&hdr->daddr, first_hop);
241 241
242 skb->priority = sk->sk_priority; 242 skb->priority = sk->sk_priority;
@@ -879,7 +879,7 @@ static inline int ip6_rt_check(struct rt6key *rt_key,
879 879
880static struct dst_entry *ip6_sk_dst_check(struct sock *sk, 880static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
881 struct dst_entry *dst, 881 struct dst_entry *dst,
882 struct flowi *fl) 882 struct flowi6 *fl6)
883{ 883{
884 struct ipv6_pinfo *np = inet6_sk(sk); 884 struct ipv6_pinfo *np = inet6_sk(sk);
885 struct rt6_info *rt = (struct rt6_info *)dst; 885 struct rt6_info *rt = (struct rt6_info *)dst;
@@ -904,11 +904,11 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
904 * sockets. 904 * sockets.
905 * 2. oif also should be the same. 905 * 2. oif also should be the same.
906 */ 906 */
907 if (ip6_rt_check(&rt->rt6i_dst, &fl->fl6_dst, np->daddr_cache) || 907 if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) ||
908#ifdef CONFIG_IPV6_SUBTREES 908#ifdef CONFIG_IPV6_SUBTREES
909 ip6_rt_check(&rt->rt6i_src, &fl->fl6_src, np->saddr_cache) || 909 ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
910#endif 910#endif
911 (fl->flowi_oif && fl->flowi_oif != dst->dev->ifindex)) { 911 (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) {
912 dst_release(dst); 912 dst_release(dst);
913 dst = NULL; 913 dst = NULL;
914 } 914 }
@@ -918,22 +918,22 @@ out:
918} 918}
919 919
920static int ip6_dst_lookup_tail(struct sock *sk, 920static int ip6_dst_lookup_tail(struct sock *sk,
921 struct dst_entry **dst, struct flowi *fl) 921 struct dst_entry **dst, struct flowi6 *fl6)
922{ 922{
923 int err; 923 int err;
924 struct net *net = sock_net(sk); 924 struct net *net = sock_net(sk);
925 925
926 if (*dst == NULL) 926 if (*dst == NULL)
927 *dst = ip6_route_output(net, sk, fl); 927 *dst = ip6_route_output(net, sk, fl6);
928 928
929 if ((err = (*dst)->error)) 929 if ((err = (*dst)->error))
930 goto out_err_release; 930 goto out_err_release;
931 931
932 if (ipv6_addr_any(&fl->fl6_src)) { 932 if (ipv6_addr_any(&fl6->saddr)) {
933 err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, 933 err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
934 &fl->fl6_dst, 934 &fl6->daddr,
935 sk ? inet6_sk(sk)->srcprefs : 0, 935 sk ? inet6_sk(sk)->srcprefs : 0,
936 &fl->fl6_src); 936 &fl6->saddr);
937 if (err) 937 if (err)
938 goto out_err_release; 938 goto out_err_release;
939 } 939 }
@@ -949,10 +949,10 @@ static int ip6_dst_lookup_tail(struct sock *sk,
949 */ 949 */
950 if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { 950 if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
951 struct inet6_ifaddr *ifp; 951 struct inet6_ifaddr *ifp;
952 struct flowi fl_gw; 952 struct flowi6 fl_gw6;
953 int redirect; 953 int redirect;
954 954
955 ifp = ipv6_get_ifaddr(net, &fl->fl6_src, 955 ifp = ipv6_get_ifaddr(net, &fl6->saddr,
956 (*dst)->dev, 1); 956 (*dst)->dev, 1);
957 957
958 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); 958 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
@@ -965,9 +965,9 @@ static int ip6_dst_lookup_tail(struct sock *sk,
965 * default router instead 965 * default router instead
966 */ 966 */
967 dst_release(*dst); 967 dst_release(*dst);
968 memcpy(&fl_gw, fl, sizeof(struct flowi)); 968 memcpy(&fl_gw6, fl6, sizeof(struct flowi6));
969 memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); 969 memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr));
970 *dst = ip6_route_output(net, sk, &fl_gw); 970 *dst = ip6_route_output(net, sk, &fl_gw6);
971 if ((err = (*dst)->error)) 971 if ((err = (*dst)->error))
972 goto out_err_release; 972 goto out_err_release;
973 } 973 }
@@ -988,23 +988,23 @@ out_err_release:
988 * ip6_dst_lookup - perform route lookup on flow 988 * ip6_dst_lookup - perform route lookup on flow
989 * @sk: socket which provides route info 989 * @sk: socket which provides route info
990 * @dst: pointer to dst_entry * for result 990 * @dst: pointer to dst_entry * for result
991 * @fl: flow to lookup 991 * @fl6: flow to lookup
992 * 992 *
993 * This function performs a route lookup on the given flow. 993 * This function performs a route lookup on the given flow.
994 * 994 *
995 * It returns zero on success, or a standard errno code on error. 995 * It returns zero on success, or a standard errno code on error.
996 */ 996 */
997int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) 997int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6)
998{ 998{
999 *dst = NULL; 999 *dst = NULL;
1000 return ip6_dst_lookup_tail(sk, dst, fl); 1000 return ip6_dst_lookup_tail(sk, dst, fl6);
1001} 1001}
1002EXPORT_SYMBOL_GPL(ip6_dst_lookup); 1002EXPORT_SYMBOL_GPL(ip6_dst_lookup);
1003 1003
1004/** 1004/**
1005 * ip6_dst_lookup_flow - perform route lookup on flow with ipsec 1005 * ip6_dst_lookup_flow - perform route lookup on flow with ipsec
1006 * @sk: socket which provides route info 1006 * @sk: socket which provides route info
1007 * @fl: flow to lookup 1007 * @fl6: flow to lookup
1008 * @final_dst: final destination address for ipsec lookup 1008 * @final_dst: final destination address for ipsec lookup
1009 * @can_sleep: we are in a sleepable context 1009 * @can_sleep: we are in a sleepable context
1010 * 1010 *
@@ -1013,29 +1013,29 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup);
1013 * It returns a valid dst pointer on success, or a pointer encoded 1013 * It returns a valid dst pointer on success, or a pointer encoded
1014 * error code. 1014 * error code.
1015 */ 1015 */
1016struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi *fl, 1016struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
1017 const struct in6_addr *final_dst, 1017 const struct in6_addr *final_dst,
1018 bool can_sleep) 1018 bool can_sleep)
1019{ 1019{
1020 struct dst_entry *dst = NULL; 1020 struct dst_entry *dst = NULL;
1021 int err; 1021 int err;
1022 1022
1023 err = ip6_dst_lookup_tail(sk, &dst, fl); 1023 err = ip6_dst_lookup_tail(sk, &dst, fl6);
1024 if (err) 1024 if (err)
1025 return ERR_PTR(err); 1025 return ERR_PTR(err);
1026 if (final_dst) 1026 if (final_dst)
1027 ipv6_addr_copy(&fl->fl6_dst, final_dst); 1027 ipv6_addr_copy(&fl6->daddr, final_dst);
1028 if (can_sleep) 1028 if (can_sleep)
1029 fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP; 1029 fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
1030 1030
1031 return xfrm_lookup(sock_net(sk), dst, fl, sk, 0); 1031 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1032} 1032}
1033EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); 1033EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
1034 1034
1035/** 1035/**
1036 * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow 1036 * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
1037 * @sk: socket which provides the dst cache and route info 1037 * @sk: socket which provides the dst cache and route info
1038 * @fl: flow to lookup 1038 * @fl6: flow to lookup
1039 * @final_dst: final destination address for ipsec lookup 1039 * @final_dst: final destination address for ipsec lookup
1040 * @can_sleep: we are in a sleepable context 1040 * @can_sleep: we are in a sleepable context
1041 * 1041 *
@@ -1047,24 +1047,24 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
1047 * It returns a valid dst pointer on success, or a pointer encoded 1047 * It returns a valid dst pointer on success, or a pointer encoded
1048 * error code. 1048 * error code.
1049 */ 1049 */
1050struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi *fl, 1050struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
1051 const struct in6_addr *final_dst, 1051 const struct in6_addr *final_dst,
1052 bool can_sleep) 1052 bool can_sleep)
1053{ 1053{
1054 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); 1054 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
1055 int err; 1055 int err;
1056 1056
1057 dst = ip6_sk_dst_check(sk, dst, fl); 1057 dst = ip6_sk_dst_check(sk, dst, fl6);
1058 1058
1059 err = ip6_dst_lookup_tail(sk, &dst, fl); 1059 err = ip6_dst_lookup_tail(sk, &dst, fl6);
1060 if (err) 1060 if (err)
1061 return ERR_PTR(err); 1061 return ERR_PTR(err);
1062 if (final_dst) 1062 if (final_dst)
1063 ipv6_addr_copy(&fl->fl6_dst, final_dst); 1063 ipv6_addr_copy(&fl6->daddr, final_dst);
1064 if (can_sleep) 1064 if (can_sleep)
1065 fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP; 1065 fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
1066 1066
1067 return xfrm_lookup(sock_net(sk), dst, fl, sk, 0); 1067 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1068} 1068}
1069EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); 1069EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
1070 1070
@@ -1145,7 +1145,7 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
1145int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, 1145int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1146 int offset, int len, int odd, struct sk_buff *skb), 1146 int offset, int len, int odd, struct sk_buff *skb),
1147 void *from, int length, int transhdrlen, 1147 void *from, int length, int transhdrlen,
1148 int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, 1148 int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6,
1149 struct rt6_info *rt, unsigned int flags, int dontfrag) 1149 struct rt6_info *rt, unsigned int flags, int dontfrag)
1150{ 1150{
1151 struct inet_sock *inet = inet_sk(sk); 1151 struct inet_sock *inet = inet_sk(sk);
@@ -1203,7 +1203,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1203 } 1203 }
1204 dst_hold(&rt->dst); 1204 dst_hold(&rt->dst);
1205 inet->cork.dst = &rt->dst; 1205 inet->cork.dst = &rt->dst;
1206 inet->cork.fl = *fl; 1206 inet->cork.fl.u.ip6 = *fl6;
1207 np->cork.hop_limit = hlimit; 1207 np->cork.hop_limit = hlimit;
1208 np->cork.tclass = tclass; 1208 np->cork.tclass = tclass;
1209 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? 1209 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
@@ -1224,7 +1224,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1224 transhdrlen += exthdrlen; 1224 transhdrlen += exthdrlen;
1225 } else { 1225 } else {
1226 rt = (struct rt6_info *)inet->cork.dst; 1226 rt = (struct rt6_info *)inet->cork.dst;
1227 fl = &inet->cork.fl; 1227 fl6 = &inet->cork.fl.u.ip6;
1228 opt = np->cork.opt; 1228 opt = np->cork.opt;
1229 transhdrlen = 0; 1229 transhdrlen = 0;
1230 exthdrlen = 0; 1230 exthdrlen = 0;
@@ -1239,7 +1239,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1239 1239
1240 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { 1240 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
1241 if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { 1241 if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
1242 ipv6_local_error(sk, EMSGSIZE, fl, mtu-exthdrlen); 1242 ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen);
1243 return -EMSGSIZE; 1243 return -EMSGSIZE;
1244 } 1244 }
1245 } 1245 }
@@ -1271,7 +1271,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1271 if (length > mtu) { 1271 if (length > mtu) {
1272 int proto = sk->sk_protocol; 1272 int proto = sk->sk_protocol;
1273 if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ 1273 if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
1274 ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen); 1274 ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
1275 return -EMSGSIZE; 1275 return -EMSGSIZE;
1276 } 1276 }
1277 1277
@@ -1516,8 +1516,8 @@ int ip6_push_pending_frames(struct sock *sk)
1516 struct ipv6hdr *hdr; 1516 struct ipv6hdr *hdr;
1517 struct ipv6_txoptions *opt = np->cork.opt; 1517 struct ipv6_txoptions *opt = np->cork.opt;
1518 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; 1518 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst;
1519 struct flowi *fl = &inet->cork.fl; 1519 struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
1520 unsigned char proto = fl->flowi_proto; 1520 unsigned char proto = fl6->flowi6_proto;
1521 int err = 0; 1521 int err = 0;
1522 1522
1523 if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL) 1523 if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
@@ -1542,7 +1542,7 @@ int ip6_push_pending_frames(struct sock *sk)
1542 if (np->pmtudisc < IPV6_PMTUDISC_DO) 1542 if (np->pmtudisc < IPV6_PMTUDISC_DO)
1543 skb->local_df = 1; 1543 skb->local_df = 1;
1544 1544
1545 ipv6_addr_copy(final_dst, &fl->fl6_dst); 1545 ipv6_addr_copy(final_dst, &fl6->daddr);
1546 __skb_pull(skb, skb_network_header_len(skb)); 1546 __skb_pull(skb, skb_network_header_len(skb));
1547 if (opt && opt->opt_flen) 1547 if (opt && opt->opt_flen)
1548 ipv6_push_frag_opts(skb, opt, &proto); 1548 ipv6_push_frag_opts(skb, opt, &proto);
@@ -1553,12 +1553,12 @@ int ip6_push_pending_frames(struct sock *sk)
1553 skb_reset_network_header(skb); 1553 skb_reset_network_header(skb);
1554 hdr = ipv6_hdr(skb); 1554 hdr = ipv6_hdr(skb);
1555 1555
1556 *(__be32*)hdr = fl->fl6_flowlabel | 1556 *(__be32*)hdr = fl6->flowlabel |
1557 htonl(0x60000000 | ((int)np->cork.tclass << 20)); 1557 htonl(0x60000000 | ((int)np->cork.tclass << 20));
1558 1558
1559 hdr->hop_limit = np->cork.hop_limit; 1559 hdr->hop_limit = np->cork.hop_limit;
1560 hdr->nexthdr = proto; 1560 hdr->nexthdr = proto;
1561 ipv6_addr_copy(&hdr->saddr, &fl->fl6_src); 1561 ipv6_addr_copy(&hdr->saddr, &fl6->saddr);
1562 ipv6_addr_copy(&hdr->daddr, final_dst); 1562 ipv6_addr_copy(&hdr->daddr, final_dst);
1563 1563
1564 skb->priority = sk->sk_priority; 1564 skb->priority = sk->sk_priority;