Commit 1009695b authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller

UDP fixes:

- respect multicast interface when connecting
parent a0faeab7
...@@ -725,6 +725,8 @@ int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -725,6 +725,8 @@ int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct inet_opt *inet = inet_sk(sk); struct inet_opt *inet = inet_sk(sk);
struct sockaddr_in *usin = (struct sockaddr_in *) uaddr; struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
struct rtable *rt; struct rtable *rt;
u32 saddr;
int oif;
int err; int err;
...@@ -736,8 +738,16 @@ int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -736,8 +738,16 @@ int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
sk_dst_reset(sk); sk_dst_reset(sk);
err = ip_route_connect(&rt, usin->sin_addr.s_addr, inet->saddr, oif = sk->bound_dev_if;
RT_CONN_FLAGS(sk), sk->bound_dev_if); saddr = inet->saddr;
if (MULTICAST(usin->sin_addr.s_addr)) {
if (!oif)
oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
}
err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr,
RT_CONN_FLAGS(sk), oif);
if (err) if (err)
return err; return err;
if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) { if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) {
......
...@@ -293,6 +293,8 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -293,6 +293,8 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return -EINVAL; return -EINVAL;
} }
sk->bound_dev_if = usin->sin6_scope_id; sk->bound_dev_if = usin->sin6_scope_id;
if (!sk->bound_dev_if && (addr_type&IPV6_ADDR_MULTICAST))
fl.oif = np->mcast_oif;
} }
/* Connect to link-local address requires an interface */ /* Connect to link-local address requires an interface */
...@@ -317,6 +319,9 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -317,6 +319,9 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
fl.uli_u.ports.dport = inet->dport; fl.uli_u.ports.dport = inet->dport;
fl.uli_u.ports.sport = inet->sport; fl.uli_u.ports.sport = inet->sport;
if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST))
fl.oif = np->mcast_oif;
if (flowlabel) { if (flowlabel) {
if (flowlabel->opt && flowlabel->opt->srcrt) { if (flowlabel->opt && flowlabel->opt->srcrt) {
struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt; struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
......
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