Commit 97be95af authored by David S. Miller's avatar David S. Miller

[IPV4]: Provide full proto/ports in flowi route lookups.

parent 01770cd0
...@@ -139,12 +139,16 @@ static inline char rt_tos2priority(u8 tos) ...@@ -139,12 +139,16 @@ static inline char rt_tos2priority(u8 tos)
return ip_tos2prio[IPTOS_TOS(tos)>>1]; return ip_tos2prio[IPTOS_TOS(tos)>>1];
} }
static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif) static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif, u8 protocol, u16 sport, u16 dport)
{ {
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dst, struct flowi fl = { .oif = oif,
.nl_u = { .ip4_u = { .daddr = dst,
.saddr = src, .saddr = src,
.tos = tos } }, .tos = tos } },
.oif = oif }; .proto = protocol,
.uli_u = { .ports =
{ .sport = sport,
.dport = dport } } };
int err; int err;
err = ip_route_output_key(rp, &fl); err = ip_route_output_key(rp, &fl);
...@@ -157,6 +161,21 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos ...@@ -157,6 +161,21 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos
return ip_route_output_key(rp, &fl); return ip_route_output_key(rp, &fl);
} }
static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport)
{
if (sport != (*rp)->fl.uli_u.ports.sport ||
dport != (*rp)->fl.uli_u.ports.dport) {
struct flowi fl;
memcpy(&fl, &(*rp)->fl, sizeof(fl));
fl.uli_u.ports.sport = sport;
fl.uli_u.ports.dport = dport;
*rp = NULL;
return ip_route_output_key(rp, &fl);
}
return 0;
}
extern void rt_bind_peer(struct rtable *rt, int create); extern void rt_bind_peer(struct rtable *rt, int create);
static inline struct inet_peer *rt_get_peer(struct rtable *rt) static inline struct inet_peer *rt_get_peer(struct rtable *rt)
......
...@@ -428,7 +428,8 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) ...@@ -428,7 +428,8 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = daddr, { .daddr = daddr,
.saddr = rt->rt_spec_dst, .saddr = rt->rt_spec_dst,
.tos = RT_TOS(skb->nh.iph->tos) } } }; .tos = RT_TOS(skb->nh.iph->tos) } },
.proto = IPPROTO_ICMP };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
goto out_unlock; goto out_unlock;
} }
...@@ -550,7 +551,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) ...@@ -550,7 +551,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
{ {
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->saddr, struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->saddr,
.saddr = saddr, .saddr = saddr,
.tos = RT_TOS(tos) } } }; .tos = RT_TOS(tos) } },
.proto = IPPROTO_ICMP };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
goto out_unlock; goto out_unlock;
} }
...@@ -577,7 +579,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) ...@@ -577,7 +579,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = icmp_param.replyopts.faddr, { .daddr = icmp_param.replyopts.faddr,
.saddr = saddr, .saddr = saddr,
.tos = RT_TOS(tos) } } }; .tos = RT_TOS(tos) } },
.proto = IPPROTO_ICMP };
ip_rt_put(rt); ip_rt_put(rt);
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
goto out_unlock; goto out_unlock;
......
...@@ -208,8 +208,9 @@ static int igmp_send_report(struct net_device *dev, u32 group, int type) ...@@ -208,8 +208,9 @@ static int igmp_send_report(struct net_device *dev, u32 group, int type)
dst = IGMP_ALL_ROUTER; dst = IGMP_ALL_ROUTER;
{ {
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dst } }, struct flowi fl = { .oif = dev->ifindex,
.oif = dev->ifindex }; .nl_u = { .ip4_u = { .daddr = dst } },
.proto = IPPROTO_IGMP };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
return -1; return -1;
} }
......
...@@ -492,6 +492,7 @@ void ipgre_err(struct sk_buff *skb, u32 info) ...@@ -492,6 +492,7 @@ void ipgre_err(struct sk_buff *skb, u32 info)
memset(&fl, 0, sizeof(fl)); memset(&fl, 0, sizeof(fl));
fl.fl4_dst = eiph->saddr; fl.fl4_dst = eiph->saddr;
fl.fl4_tos = RT_TOS(eiph->tos); fl.fl4_tos = RT_TOS(eiph->tos);
fl.proto = IPPROTO_GRE;
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl)) {
kfree_skb(skb2); kfree_skb(skb2);
return; return;
...@@ -757,11 +758,12 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -757,11 +758,12 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
} }
{ {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = tunnel->parms.link,
.nl_u = { .ip4_u =
{ .daddr = dst, { .daddr = dst,
.saddr = tiph->saddr, .saddr = tiph->saddr,
.tos = RT_TOS(tos) } }, .tos = RT_TOS(tos) } },
.oif = tunnel->parms.link }; .proto = IPPROTO_GRE };
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl)) {
tunnel->stat.tx_carrier_errors++; tunnel->stat.tx_carrier_errors++;
goto tx_error; goto tx_error;
...@@ -1118,11 +1120,12 @@ static int ipgre_open(struct net_device *dev) ...@@ -1118,11 +1120,12 @@ static int ipgre_open(struct net_device *dev)
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
if (MULTICAST(t->parms.iph.daddr)) { if (MULTICAST(t->parms.iph.daddr)) {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = t->parms.link,
.nl_u = { .ip4_u =
{ .daddr = t->parms.iph.daddr, { .daddr = t->parms.iph.daddr,
.saddr = t->parms.iph.saddr, .saddr = t->parms.iph.saddr,
.tos = RT_TOS(t->parms.iph.tos) } }, .tos = RT_TOS(t->parms.iph.tos) } },
.oif = t->parms.link }; .proto = IPPROTO_GRE };
struct rtable *rt; struct rtable *rt;
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl)) {
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
...@@ -1194,11 +1197,12 @@ static int ipgre_tunnel_init(struct net_device *dev) ...@@ -1194,11 +1197,12 @@ static int ipgre_tunnel_init(struct net_device *dev)
/* Guess output device to choose reasonable mtu and hard_header_len */ /* Guess output device to choose reasonable mtu and hard_header_len */
if (iph->daddr) { if (iph->daddr) {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = tunnel->parms.link,
.nl_u = { .ip4_u =
{ .daddr = iph->daddr, { .daddr = iph->daddr,
.saddr = iph->saddr, .saddr = iph->saddr,
.tos = RT_TOS(iph->tos) } }, .tos = RT_TOS(iph->tos) } },
.oif = tunnel->parms.link }; .proto = IPPROTO_GRE };
struct rtable *rt; struct rtable *rt;
if (!ip_route_output_key(&rt, &fl)) { if (!ip_route_output_key(&rt, &fl)) {
tdev = rt->u.dst.dev; tdev = rt->u.dst.dev;
......
...@@ -118,7 +118,9 @@ ip_do_nat(struct sk_buff *skb) ...@@ -118,7 +118,9 @@ ip_do_nat(struct sk_buff *skb)
if (ciph->daddr != osaddr) { if (ciph->daddr != osaddr) {
struct fib_result res; struct fib_result res;
unsigned flags = 0; unsigned flags = 0;
struct flowi fl = { .nl_u = struct flowi fl = {
.iif = skb->dev->ifindex,
.nl_u =
{ .ip4_u = { .ip4_u =
{ .daddr = ciph->saddr, { .daddr = ciph->saddr,
.saddr = ciph->daddr, .saddr = ciph->daddr,
...@@ -126,7 +128,7 @@ ip_do_nat(struct sk_buff *skb) ...@@ -126,7 +128,7 @@ ip_do_nat(struct sk_buff *skb)
.tos = RT_TOS(ciph->tos) .tos = RT_TOS(ciph->tos)
#endif #endif
} }, } },
.iif = skb->dev->ifindex }; .proto = ciph->protocol };
/* Use fib_lookup() until we get our own /* Use fib_lookup() until we get our own
* hash table of NATed hosts -- Rani * hash table of NATed hosts -- Rani
......
...@@ -306,15 +306,19 @@ int ip_queue_xmit(struct sk_buff *skb) ...@@ -306,15 +306,19 @@ int ip_queue_xmit(struct sk_buff *skb)
daddr = opt->faddr; daddr = opt->faddr;
{ {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = sk->bound_dev_if,
.nl_u = { .ip4_u =
{ .daddr = daddr, { .daddr = daddr,
.saddr = inet->saddr, .saddr = inet->saddr,
.tos = RT_CONN_FLAGS(sk) } }, .tos = RT_CONN_FLAGS(sk) } },
.oif = sk->bound_dev_if }; .proto = sk->protocol,
.uli_u = { .ports =
{ .sport = inet->sport,
.dport = inet->dport } } };
/* If this fails, retransmit mechanism of transport layer will /* If this fails, retransmit mechanism of transport layer will
* keep trying until route appears or the connection times itself * keep trying until route appears or the connection times
* out. * itself out.
*/ */
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
goto no_route; goto no_route;
...@@ -1206,7 +1210,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar ...@@ -1206,7 +1210,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = daddr, { .daddr = daddr,
.saddr = rt->rt_spec_dst, .saddr = rt->rt_spec_dst,
.tos = RT_TOS(skb->nh.iph->tos) } } }; .tos = RT_TOS(skb->nh.iph->tos) } },
.proto = sk->protocol };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
return; return;
} }
......
...@@ -421,6 +421,7 @@ void ipip_err(struct sk_buff *skb, u32 info) ...@@ -421,6 +421,7 @@ void ipip_err(struct sk_buff *skb, u32 info)
memset(&fl, 0, sizeof(fl)); memset(&fl, 0, sizeof(fl));
fl.fl4_daddr = eiph->saddr; fl.fl4_daddr = eiph->saddr;
fl.fl4_tos = RT_TOS(eiph->tos); fl.fl4_tos = RT_TOS(eiph->tos);
fl.proto = IPPROTO_IPIP;
if (ip_route_output_key(&rt, &key)) { if (ip_route_output_key(&rt, &key)) {
kfree_skb(skb2); kfree_skb(skb2);
return; return;
...@@ -568,11 +569,12 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -568,11 +569,12 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
} }
{ {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = tunnel->parms.link,
.nl_u = { .ip4_u =
{ .daddr = dst, { .daddr = dst,
.saddr = tiph->saddr, .saddr = tiph->saddr,
.tos = RT_TOS(tos) } }, .tos = RT_TOS(tos) } },
.oif = tunnel->parms.link }; .proto = IPPROTO_IPIP };
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl)) {
tunnel->stat.tx_carrier_errors++; tunnel->stat.tx_carrier_errors++;
goto tx_error_icmp; goto tx_error_icmp;
...@@ -836,11 +838,12 @@ static int ipip_tunnel_init(struct net_device *dev) ...@@ -836,11 +838,12 @@ static int ipip_tunnel_init(struct net_device *dev)
ipip_tunnel_init_gen(dev); ipip_tunnel_init_gen(dev);
if (iph->daddr) { if (iph->daddr) {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = tunnel->parms.link,
.nl_u = { .ip4_u =
{ .daddr = iph->daddr, { .daddr = iph->daddr,
.saddr = iph->saddr, .saddr = iph->saddr,
.tos = RT_TOS(iph->tos) } }, .tos = RT_TOS(iph->tos) } },
.oif = tunnel->parms.link }; .proto = IPPROTO_IPIP };
struct rtable *rt; struct rtable *rt;
if (!ip_route_output_key(&rt, &fl)) { if (!ip_route_output_key(&rt, &fl)) {
tdev = rt->u.dst.dev; tdev = rt->u.dst.dev;
......
...@@ -1146,19 +1146,21 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, ...@@ -1146,19 +1146,21 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
#endif #endif
if (vif->flags&VIFF_TUNNEL) { if (vif->flags&VIFF_TUNNEL) {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = vif->link,
.nl_u = { .ip4_u =
{ .daddr = vif->remote, { .daddr = vif->remote,
.saddr = vif->local, .saddr = vif->local,
.tos = RT_TOS(iph->tos) } }, .tos = RT_TOS(iph->tos) } },
.oif = vif->link }; .proto = IPPROTO_IPIP };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
return; return;
encap = sizeof(struct iphdr); encap = sizeof(struct iphdr);
} else { } else {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = vif->link,
.nl_u = { .ip4_u =
{ .daddr = iph->daddr, { .daddr = iph->daddr,
.tos = RT_TOS(iph->tos) } }, .tos = RT_TOS(iph->tos) } },
.oif = vif->link }; .proto = IPPROTO_IPIP };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
return; return;
} }
......
...@@ -420,11 +420,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ...@@ -420,11 +420,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
} }
{ {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = ipc.oif,
.nl_u = { .ip4_u =
{ .daddr = daddr, { .daddr = daddr,
.saddr = saddr, .saddr = saddr,
.tos = tos } }, .tos = tos } },
.oif = ipc.oif }; .proto = IPPROTO_RAW };
err = ip_route_output_key(&rt, &fl); err = ip_route_output_key(&rt, &fl);
} }
if (err) if (err)
......
...@@ -177,7 +177,11 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ...@@ -177,7 +177,11 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
opt->faddr : opt->faddr :
req->af.v4_req.rmt_addr), req->af.v4_req.rmt_addr),
.saddr = req->af.v4_req.loc_addr, .saddr = req->af.v4_req.loc_addr,
.tos = RT_CONN_FLAGS(sk) } } }; .tos = RT_CONN_FLAGS(sk) } },
.proto = IPPROTO_TCP,
.uli_u = { .ports =
{ .sport = skb->h.th->dest,
.dport = skb->h.th->source } } };
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl)) {
tcp_openreq_free(req); tcp_openreq_free(req);
goto out; goto out;
......
...@@ -770,7 +770,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -770,7 +770,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
} }
tmp = ip_route_connect(&rt, nexthop, inet->saddr, tmp = ip_route_connect(&rt, nexthop, inet->saddr,
RT_CONN_FLAGS(sk), sk->bound_dev_if); RT_CONN_FLAGS(sk), sk->bound_dev_if,
IPPROTO_TCP,
inet->sport, usin->sin_port);
if (tmp < 0) if (tmp < 0)
return tmp; return tmp;
...@@ -779,10 +781,6 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -779,10 +781,6 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return -ENETUNREACH; return -ENETUNREACH;
} }
__sk_dst_set(sk, &rt->u.dst);
tcp_v4_setup_caps(sk, &rt->u.dst);
tp->ext_header_len += rt->u.dst.header_len;
if (!inet->opt || !inet->opt->srr) if (!inet->opt || !inet->opt->srr)
daddr = rt->rt_dst; daddr = rt->rt_dst;
...@@ -831,6 +829,19 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -831,6 +829,19 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
if (err) if (err)
goto failure; goto failure;
err = ip_route_newports(&rt, inet->sport, inet->dport);
if (err)
goto failure;
/* OK, now commit destination to socket. */
__sk_dst_set(sk, &rt->u.dst);
tcp_v4_setup_caps(sk, &rt->u.dst);
/* DAVEM REDPEN: This used to sit above forced ext_header_len = 0
* above, it was real bug. Is this one correct?
*/
tp->ext_header_len += rt->u.dst.header_len;
if (!tp->write_seq) if (!tp->write_seq)
tp->write_seq = secure_tcp_sequence_number(inet->saddr, tp->write_seq = secure_tcp_sequence_number(inet->saddr,
inet->daddr, inet->daddr,
...@@ -846,8 +857,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -846,8 +857,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return 0; return 0;
failure: failure:
/* This unhashes the socket and releases the local port, if necessary. */
tcp_set_state(sk, TCP_CLOSE); tcp_set_state(sk, TCP_CLOSE);
__sk_dst_reset(sk); ip_rt_put(rt);
sk->route_caps = 0; sk->route_caps = 0;
inet->dport = 0; inet->dport = 0;
return err; return err;
...@@ -1265,13 +1277,17 @@ static struct dst_entry* tcp_v4_route_req(struct sock *sk, ...@@ -1265,13 +1277,17 @@ static struct dst_entry* tcp_v4_route_req(struct sock *sk,
{ {
struct rtable *rt; struct rtable *rt;
struct ip_options *opt = req->af.v4_req.opt; struct ip_options *opt = req->af.v4_req.opt;
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = sk->bound_dev_if,
.nl_u = { .ip4_u =
{ .daddr = ((opt && opt->srr) ? { .daddr = ((opt && opt->srr) ?
opt->faddr : opt->faddr :
req->af.v4_req.rmt_addr), req->af.v4_req.rmt_addr),
.saddr = req->af.v4_req.loc_addr, .saddr = req->af.v4_req.loc_addr,
.tos = RT_CONN_FLAGS(sk) } }, .tos = RT_CONN_FLAGS(sk) } },
.oif = sk->bound_dev_if }; .proto = IPPROTO_TCP,
.uli_u = { .ports =
{ .sport = inet_sk(sk)->sport,
.dport = req->rmt_port } } };
if (ip_route_output_key(&rt, &fl)) { if (ip_route_output_key(&rt, &fl)) {
IP_INC_STATS_BH(IpOutNoRoutes); IP_INC_STATS_BH(IpOutNoRoutes);
...@@ -1864,7 +1880,9 @@ static int tcp_v4_reselect_saddr(struct sock *sk) ...@@ -1864,7 +1880,9 @@ static int tcp_v4_reselect_saddr(struct sock *sk)
/* Query new route. */ /* Query new route. */
err = ip_route_connect(&rt, daddr, 0, err = ip_route_connect(&rt, daddr, 0,
RT_TOS(inet->tos) | sk->localroute, RT_TOS(inet->tos) | sk->localroute,
sk->bound_dev_if); sk->bound_dev_if,
IPPROTO_TCP,
inet->sport, inet->dport);
if (err) if (err)
return err; return err;
...@@ -1914,11 +1932,15 @@ int tcp_v4_rebuild_header(struct sock *sk) ...@@ -1914,11 +1932,15 @@ int tcp_v4_rebuild_header(struct sock *sk)
daddr = inet->opt->faddr; daddr = inet->opt->faddr;
{ {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = sk->bound_dev_if,
.nl_u = { .ip4_u =
{ .daddr = daddr, { .daddr = daddr,
.saddr = inet->saddr, .saddr = inet->saddr,
.tos = RT_CONN_FLAGS(sk) } }, .tos = RT_CONN_FLAGS(sk) } },
.oif = sk->bound_dev_if }; .proto = IPPROTO_TCP,
.uli_u = { .ports =
{ .sport = inet->sport,
.dport = inet->dport } } };
err = ip_route_output_key(&rt, &fl); err = ip_route_output_key(&rt, &fl);
} }
......
...@@ -586,11 +586,15 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ...@@ -586,11 +586,15 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
rt = (struct rtable*)sk_dst_check(sk, 0); rt = (struct rtable*)sk_dst_check(sk, 0);
if (rt == NULL) { if (rt == NULL) {
struct flowi fl = { .nl_u = { .ip4_u = struct flowi fl = { .oif = ipc.oif,
.nl_u = { .ip4_u =
{ .daddr = faddr, { .daddr = faddr,
.saddr = saddr, .saddr = saddr,
.tos = tos } }, .tos = tos } },
.oif = ipc.oif }; .proto = IPPROTO_UDP,
.uli_u = { .ports =
{ .sport = inet->sport,
.dport = dport } } };
err = ip_route_output_key(&rt, &fl); err = ip_route_output_key(&rt, &fl);
if (err) if (err)
goto out; goto out;
...@@ -872,7 +876,9 @@ int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -872,7 +876,9 @@ int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
saddr = inet->mc_addr; saddr = inet->mc_addr;
} }
err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr, err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr,
RT_CONN_FLAGS(sk), oif); RT_CONN_FLAGS(sk), oif,
IPPROTO_UDP,
inet->sport, usin->sin_port);
if (err) if (err)
return err; return err;
if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) { if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) {
......
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