Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47985
b: refs/heads/master
c: 9575648
h: refs/heads/master
i:
  47983: d441655
v: v3
  • Loading branch information
Chuck Lever authored and Linus Torvalds committed Feb 12, 2007
1 parent d556096 commit 9390941
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cdd88b9f3ed5013de0f1085e0e2f9123c798609d
refs/heads/master: 95756482c9bfa375418c5a32455494a3042f65cd
5 changes: 5 additions & 0 deletions trunk/include/linux/sunrpc/svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ static inline struct sockaddr_in *svc_addr_in(struct svc_rqst *rqst)
return (struct sockaddr_in *) &rqst->rq_addr;
}

static inline struct sockaddr_in6 *svc_addr_in6(struct svc_rqst *rqst)
{
return (struct sockaddr_in6 *) &rqst->rq_addr;
}

static inline struct sockaddr *svc_addr(struct svc_rqst *rqst)
{
return (struct sockaddr *) &rqst->rq_addr;
Expand Down
53 changes: 43 additions & 10 deletions trunk/net/sunrpc/svcsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,13 +721,53 @@ svc_write_space(struct sock *sk)
}
}

static void svc_udp_get_sender_address(struct svc_rqst *rqstp,
struct sk_buff *skb)
{
switch (rqstp->rq_sock->sk_sk->sk_family) {
case AF_INET: {
/* this seems to come from net/ipv4/udp.c:udp_recvmsg */
struct sockaddr_in *sin = svc_addr_in(rqstp);

sin->sin_family = AF_INET;
sin->sin_port = skb->h.uh->source;
sin->sin_addr.s_addr = skb->nh.iph->saddr;
rqstp->rq_addrlen = sizeof(struct sockaddr_in);
/* Remember which interface received this request */
rqstp->rq_daddr.addr.s_addr = skb->nh.iph->daddr;
}
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6: {
/* this is derived from net/ipv6/udp.c:udpv6_recvmesg */
struct sockaddr_in6 *sin6 = svc_addr_in6(rqstp);

sin6->sin6_family = AF_INET6;
sin6->sin6_port = skb->h.uh->source;
sin6->sin6_flowinfo = 0;
sin6->sin6_scope_id = 0;
if (ipv6_addr_type(&sin6->sin6_addr) &
IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id = IP6CB(skb)->iif;
ipv6_addr_copy(&sin6->sin6_addr,
&skb->nh.ipv6h->saddr);
rqstp->rq_addrlen = sizeof(struct sockaddr_in);
/* Remember which interface received this request */
ipv6_addr_copy(&rqstp->rq_daddr.addr6,
&skb->nh.ipv6h->saddr);
}
break;
#endif
}
return;
}

/*
* Receive a datagram from a UDP socket.
*/
static int
svc_udp_recvfrom(struct svc_rqst *rqstp)
{
struct sockaddr_in *sin = svc_addr_in(rqstp);
struct svc_sock *svsk = rqstp->rq_sock;
struct svc_serv *serv = svsk->sk_server;
struct sk_buff *skb;
Expand Down Expand Up @@ -785,16 +825,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
len = skb->len - sizeof(struct udphdr);
rqstp->rq_arg.len = len;

rqstp->rq_prot = IPPROTO_UDP;

/* Get sender address */
sin->sin_family = AF_INET;
sin->sin_port = skb->h.uh->source;
sin->sin_addr.s_addr = skb->nh.iph->saddr;
rqstp->rq_addrlen = sizeof(struct sockaddr_in);
rqstp->rq_prot = IPPROTO_UDP;

/* Remember which interface received this request */
rqstp->rq_daddr.addr.s_addr = skb->nh.iph->daddr;
svc_udp_get_sender_address(rqstp, skb);

if (skb_is_nonlinear(skb)) {
/* we have to copy */
Expand Down

0 comments on commit 9390941

Please sign in to comment.