Commit d9d8da80 authored by David S. Miller's avatar David S. Miller

inet: Pass flowi to ->queue_xmit().

This allows us to acquire the exact route keying information from the
protocol, however that might be managed.

It handles all of the possibilities, from the simplest case of storing
the key in inet->cork.fl to the more complex setup SCTP has where
individual transports determine the flow.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0e734419
...@@ -41,5 +41,5 @@ extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk, ...@@ -41,5 +41,5 @@ extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
extern int inet6_csk_xmit(struct sk_buff *skb); extern int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl);
#endif /* _INET6_CONNECTION_SOCK_H */ #endif /* _INET6_CONNECTION_SOCK_H */
...@@ -36,7 +36,7 @@ struct tcp_congestion_ops; ...@@ -36,7 +36,7 @@ struct tcp_congestion_ops;
* (i.e. things that depend on the address family) * (i.e. things that depend on the address family)
*/ */
struct inet_connection_sock_af_ops { struct inet_connection_sock_af_ops {
int (*queue_xmit)(struct sk_buff *skb); int (*queue_xmit)(struct sk_buff *skb, struct flowi *fl);
void (*send_check)(struct sock *sk, struct sk_buff *skb); void (*send_check)(struct sock *sk, struct sk_buff *skb);
int (*rebuild_header)(struct sock *sk); int (*rebuild_header)(struct sock *sk);
int (*conn_request)(struct sock *sk, struct sk_buff *skb); int (*conn_request)(struct sock *sk, struct sk_buff *skb);
......
...@@ -104,7 +104,7 @@ extern int ip_do_nat(struct sk_buff *skb); ...@@ -104,7 +104,7 @@ extern int ip_do_nat(struct sk_buff *skb);
extern void ip_send_check(struct iphdr *ip); extern void ip_send_check(struct iphdr *ip);
extern int __ip_local_out(struct sk_buff *skb); extern int __ip_local_out(struct sk_buff *skb);
extern int ip_local_out(struct sk_buff *skb); extern int ip_local_out(struct sk_buff *skb);
extern int ip_queue_xmit(struct sk_buff *skb); extern int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl);
extern void ip_init(void); extern void ip_init(void);
extern int ip_append_data(struct sock *sk, extern int ip_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len, int getfrag(void *from, char *to, int offset, int len,
......
...@@ -43,7 +43,7 @@ static void dccp_skb_entail(struct sock *sk, struct sk_buff *skb) ...@@ -43,7 +43,7 @@ static void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
{ {
if (likely(skb != NULL)) { if (likely(skb != NULL)) {
const struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_connection_sock *icsk = inet_csk(sk);
struct dccp_sock *dp = dccp_sk(sk); struct dccp_sock *dp = dccp_sk(sk);
struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
...@@ -136,7 +136,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) ...@@ -136,7 +136,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
DCCP_INC_STATS(DCCP_MIB_OUTSEGS); DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
err = icsk->icsk_af_ops->queue_xmit(skb); err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
return net_xmit_eval(err); return net_xmit_eval(err);
} }
return -ENOBUFS; return -ENOBUFS;
......
...@@ -312,7 +312,7 @@ int ip_output(struct sk_buff *skb) ...@@ -312,7 +312,7 @@ int ip_output(struct sk_buff *skb)
!(IPCB(skb)->flags & IPSKB_REROUTED)); !(IPCB(skb)->flags & IPSKB_REROUTED));
} }
int ip_queue_xmit(struct sk_buff *skb) int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl)
{ {
struct sock *sk = skb->sk; struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
...@@ -332,7 +332,7 @@ int ip_queue_xmit(struct sk_buff *skb) ...@@ -332,7 +332,7 @@ int ip_queue_xmit(struct sk_buff *skb)
goto packet_routed; goto packet_routed;
/* Make sure we can route this packet. */ /* Make sure we can route this packet. */
fl4 = &inet->cork.fl.u.ip4; fl4 = &fl->u.ip4;
rt = (struct rtable *)__sk_dst_check(sk, 0); rt = (struct rtable *)__sk_dst_check(sk, 0);
if (rt == NULL) { if (rt == NULL) {
__be32 daddr; __be32 daddr;
......
...@@ -899,7 +899,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, ...@@ -899,7 +899,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS,
tcp_skb_pcount(skb)); tcp_skb_pcount(skb));
err = icsk->icsk_af_ops->queue_xmit(skb); err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
if (likely(err <= 0)) if (likely(err <= 0))
return err; return err;
......
...@@ -203,7 +203,7 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) ...@@ -203,7 +203,7 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
return dst; return dst;
} }
int inet6_csk_xmit(struct sk_buff *skb) int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
{ {
struct sock *sk = skb->sk; struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
......
...@@ -954,7 +954,7 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf) ...@@ -954,7 +954,7 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
} }
static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
size_t data_len) struct flowi *fl, size_t data_len)
{ {
struct l2tp_tunnel *tunnel = session->tunnel; struct l2tp_tunnel *tunnel = session->tunnel;
unsigned int len = skb->len; unsigned int len = skb->len;
...@@ -987,7 +987,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, ...@@ -987,7 +987,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
/* Queue the packet to IP for output */ /* Queue the packet to IP for output */
skb->local_df = 1; skb->local_df = 1;
error = ip_queue_xmit(skb); error = ip_queue_xmit(skb, fl);
/* Update stats */ /* Update stats */
if (error >= 0) { if (error >= 0) {
...@@ -1028,6 +1028,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len ...@@ -1028,6 +1028,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
int data_len = skb->len; int data_len = skb->len;
struct l2tp_tunnel *tunnel = session->tunnel; struct l2tp_tunnel *tunnel = session->tunnel;
struct sock *sk = tunnel->sock; struct sock *sk = tunnel->sock;
struct flowi *fl;
struct udphdr *uh; struct udphdr *uh;
struct inet_sock *inet; struct inet_sock *inet;
__wsum csum; __wsum csum;
...@@ -1070,10 +1071,11 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len ...@@ -1070,10 +1071,11 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
skb_dst_drop(skb); skb_dst_drop(skb);
skb_dst_set(skb, dst_clone(__sk_dst_get(sk))); skb_dst_set(skb, dst_clone(__sk_dst_get(sk)));
inet = inet_sk(sk);
fl = &inet->cork.fl;
switch (tunnel->encap) { switch (tunnel->encap) {
case L2TP_ENCAPTYPE_UDP: case L2TP_ENCAPTYPE_UDP:
/* Setup UDP header */ /* Setup UDP header */
inet = inet_sk(sk);
__skb_push(skb, sizeof(*uh)); __skb_push(skb, sizeof(*uh));
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
uh = udp_hdr(skb); uh = udp_hdr(skb);
...@@ -1111,7 +1113,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len ...@@ -1111,7 +1113,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
l2tp_skb_set_owner_w(skb, sk); l2tp_skb_set_owner_w(skb, sk);
l2tp_xmit_core(session, skb, data_len); l2tp_xmit_core(session, skb, fl, data_len);
out_unlock: out_unlock:
bh_unlock_sock(sk); bh_unlock_sock(sk);
......
...@@ -508,7 +508,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m ...@@ -508,7 +508,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
skb_dst_set(skb, dst_clone(&rt->dst)); skb_dst_set(skb, dst_clone(&rt->dst));
/* Queue the packet to IP for output */ /* Queue the packet to IP for output */
rc = ip_queue_xmit(skb); rc = ip_queue_xmit(skb, &inet->cork.fl);
error: error:
/* Update stats */ /* Update stats */
......
...@@ -855,7 +855,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, ...@@ -855,7 +855,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
IP_PMTUDISC_DO : IP_PMTUDISC_DONT; IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
return ip_queue_xmit(skb); return ip_queue_xmit(skb, &transport->fl);
} }
static struct sctp_af sctp_af_inet; static struct sctp_af sctp_af_inet;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment