lkml.org 
[lkml]   [2000]   [Feb]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectAn IP alias patch for sunrpc in kernel
When you access an NFS server, which has IP aliases, through NAT over
UDP, sunrpc in kernel has to make sure to use its IP address, where
the client sent a UDP packet, when sending reply back to the client.
Otherwise, the reply may not go through NAT. This patch tries to fix
this problem.


--
H.J. Lu (hjl@gnu.org)
---
--- linux-2.2.14/include/linux/sunrpc/svc.h.alias Thu Feb 17 12:17:42 2000
+++ linux-2.2.14/include/linux/sunrpc/svc.h Thu Feb 17 13:05:04 2000
@@ -91,6 +91,8 @@ struct svc_rqst {
struct svc_rqst * rq_next;
struct svc_sock * rq_sock; /* socket */
struct sockaddr_in rq_addr; /* peer address */
+ char rq_mesg [sizeof (struct cmsghdr)
+ + sizeof (struct in_pktinfo)];
int rq_addrlen;

struct svc_serv * rq_server; /* RPC service definition */
--- linux-2.2.14/net/sunrpc/svcsock.c.alias Thu Feb 17 12:24:17 2000
+++ linux-2.2.14/net/sunrpc/svcsock.c Thu Feb 17 15:56:15 2000
@@ -249,8 +249,14 @@ svc_sendto(struct svc_rqst *rqstp, struc
msg.msg_namelen = sizeof(rqstp->rq_addr);
msg.msg_iov = iov;
msg.msg_iovlen = nr;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
+ if (sock->type == SOCK_DGRAM) {
+ msg.msg_control = &rqstp->rq_mesg [0];
+ msg.msg_controllen = sizeof (rqstp->rq_mesg);
+ }
+ else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }

#if LINUX_VERSION_CODE >= 0x020100
msg.msg_flags = MSG_DONTWAIT;
@@ -359,6 +365,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
struct sk_buff *skb;
u32 *data;
int err, len;
+ struct cmsghdr *cm;
+ struct in_pktinfo *info;
+ struct rtable *rt;

svsk->sk_data = 0;
while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
@@ -390,6 +399,24 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
#else
rqstp->rq_addr.sin_addr.s_addr = skb->saddr;
#endif
+
+ cm = (struct cmsghdr *) &rqstp->rq_mesg [0];
+ info = (struct in_pktinfo *)
+ &rqstp->rq_mesg [sizeof(struct cmsghdr)];
+ rt = (struct rtable *)skb->dst;
+
+ cm->cmsg_level = SOL_IP;
+ cm->cmsg_type = IP_PKTINFO;
+ cm->cmsg_len = CMSG_LEN (sizeof (struct in_pktinfo));
+ info->ipi_addr.s_addr = skb->nh.iph->daddr;
+ if (rt) {
+ info->ipi_ifindex = rt->rt_iif;
+ info->ipi_spec_dst.s_addr = rt->rt_spec_dst;
+ }
+ else {
+ info->ipi_ifindex = 0;
+ info->ipi_spec_dst.s_addr = 0;
+ }

if (serv->sv_stats)
serv->sv_stats->netudpcnt++;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:56    [W:0.027 / U:0.188 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site