patch-2.1.15 linux/net/ipx/af_ipx.c
Next file: linux/net/netbeui/README
Previous file: linux/net/ipv6/udp.c
Back to the patch index
Back to the overall index
- Lines: 578
- Date:
Thu Dec 12 16:54:26 1996
- Orig file:
v2.1.14/linux/net/ipx/af_ipx.c
- Orig date:
Sat Nov 30 12:03:13 1996
diff -u --recursive --new-file v2.1.14/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
@@ -108,6 +108,8 @@
static struct datalink_proto *p8023_datalink = NULL;
static struct datalink_proto *pSNAP_datalink = NULL;
+static struct proto_ops ipx_dgram_ops;
+
static ipx_route *ipx_routes = NULL;
static ipx_interface *ipx_interfaces = NULL;
static ipx_interface *ipx_primary_net = NULL;
@@ -160,9 +162,9 @@
*/
static void
-ipx_remove_socket(ipx_socket *sk)
+ipx_remove_socket(struct sock *sk)
{
- ipx_socket *s;
+ struct sock *s;
ipx_interface *intrfc;
unsigned long flags;
@@ -202,7 +204,7 @@
*/
static void
-ipx_destroy_socket(ipx_socket *sk)
+ipx_destroy_socket(struct sock *sk)
{
struct sk_buff *skb;
@@ -258,9 +260,9 @@
/* Sockets are bound to a particular IPX interface. */
static void
-ipxitf_insert_socket(ipx_interface *intrfc, ipx_socket *sk)
+ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk)
{
- ipx_socket *s;
+ struct sock *s;
sk->protinfo.af_ipx.intrfc = intrfc;
sk->next = NULL;
@@ -273,10 +275,10 @@
}
}
-static ipx_socket *
+static struct sock *
ipxitf_find_socket(ipx_interface *intrfc, unsigned short port)
{
- ipx_socket *s;
+ struct sock *s;
for (s=intrfc->if_sklist;
(s != NULL) && (s->protinfo.af_ipx.port != port);
@@ -288,11 +290,11 @@
#ifdef CONFIG_IPX_INTERN
-static ipx_socket *
+static struct sock *
ipxitf_find_internal_socket(ipx_interface *intrfc,
unsigned char *node, unsigned short port)
{
- ipx_socket *s = intrfc->if_sklist;
+ struct sock *s = intrfc->if_sklist;
while (s != NULL)
{
@@ -313,7 +315,7 @@
ipxitf_down(ipx_interface *intrfc)
{
ipx_interface *i;
- ipx_socket *s, *t;
+ struct sock *s, *t;
/* Delete all routes associated with this interface */
ipxrtr_del_routes(intrfc);
@@ -402,7 +404,7 @@
ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
{
ipx_packet *ipx = (ipx_packet *)(skb->h.raw);
- ipx_socket *s;
+ struct sock *s;
int is_broadcast = (memcmp(ipx->ipx_dest.node, ipx_broadcast_node,
IPX_NODE_LEN) == 0);
@@ -424,7 +426,7 @@
skb1 = skb_clone(skb, GFP_ATOMIC);
if (skb1 != NULL)
{
- skb1->arp = skb1->free = 1;
+ skb1->arp = 1;
}
else
{
@@ -466,7 +468,7 @@
ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
{
ipx_packet *ipx = (ipx_packet *)(skb->h.raw);
- ipx_socket *sock1 = NULL, *sock2 = NULL;
+ struct sock *sock1 = NULL, *sock2 = NULL;
struct sk_buff *skb1 = NULL, *skb2 = NULL;
sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
@@ -523,8 +525,8 @@
if (copy)
{
skb1 = skb_clone(skb, GFP_ATOMIC);
- if (skb1 != NULL)
- skb1->arp = skb1->free = 1;
+ if (skb1)
+ skb1->arp=1;
}
else
{
@@ -542,7 +544,7 @@
{
skb2 = skb_clone(skb1, GFP_ATOMIC);
if (skb2 != NULL)
- skb2->arp = skb2->free = 1;
+ skb2->arp = 1;
}
else
skb2 = skb1;
@@ -570,7 +572,7 @@
/* Hopefully, most cases */
if (in_offset >= out_offset) {
- skb->arp = skb->free = 1;
+ skb->arp = 1;
return skb;
}
@@ -580,7 +582,6 @@
if (skb2 != NULL) {
skb_reserve(skb2,out_offset);
skb2->h.raw=skb_put(skb2,skb->len);
- skb2->free=1;
skb2->arp=1;
memcpy(skb2->h.raw, skb->h.raw, skb->len);
}
@@ -622,11 +623,7 @@
/*
* Don't charge sender
*/
- if(skb->sk)
- {
- atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
- skb->sk=NULL;
- }
+ skb_orphan(skb);
/*
* Will charge receiver
*/
@@ -637,11 +634,8 @@
*/
if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
{
- if (!send_to_wire && skb->sk)
- {
- atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
- skb->sk=NULL;
- }
+ if (!send_to_wire)
+ skb_orphan(skb);
ipxitf_demux_socket(intrfc, skb, send_to_wire);
if (!send_to_wire)
return 0;
@@ -702,14 +696,14 @@
*/
dump_pkt("IPX snd:", (ipx_packet *)skb->h.raw);
- dump_data("ETH hdr:", skb->data, skb->h.raw - skb->data);
+ dump_data("ETH hdr:", skb->sk, skb->h.raw - skb->sk);
#endif
/*
* Send it out
*/
-
- dev_queue_xmit(skb, dev, SOPRI_NORMAL);
+ skb->priority = SOPRI_NORMAL;
+ dev_queue_xmit(skb);
return 0;
}
@@ -767,6 +761,74 @@
}
}
+#ifdef CONFIG_IPX_PPROP_ROUTING
+ if( ipx->ipx_type == IPX_TYPE_PPROP && ipx->ipx_tctrl < 8 ) {
+ int i;
+ ipx_interface *ifcs;
+ struct sk_buff *skb2;
+ long *l;
+ char *c;
+
+#ifdef DEBUG_IPX_PPROP_ROUTING
+ printk(KERN_INFO "IPX: PPROP packet received\n"
+ " Src: %8x:%02x:%02x:%02x:%02x:%02x:%02x:%d/%d\n",
+ htonl(ipx->ipx_source.net),
+ ipx->ipx_source.node[0], ipx->ipx_source.node[1],
+ ipx->ipx_source.node[2], ipx->ipx_source.node[3],
+ ipx->ipx_source.node[4], ipx->ipx_source.node[5],
+ htons(ipx->ipx_source.sock),
+ htons(ipx->ipx_dest.sock)
+ );
+#endif
+
+ c = (char *) skb->data;
+ c += sizeof( struct ipx_packet );
+
+ l = (long *) c;
+
+#ifdef DEBUG_IPX_PPROP_ROUTING
+ printk( "IPX: Routing PPROP from net num %08x\n", (unsigned int) htonl(intrfc->if_netnum) );
+ for( i = 0 ; i < ipx->ipx_tctrl ; i++ )
+ printk( "IPX: Routing PPROP seen net num %08x\n", (unsigned int) htonl(*l++) );
+ l = (long *) c;
+#endif
+ i = 0;
+ /* dump packet if too many hops or already seen this net */
+ if( ipx->ipx_tctrl < 8 )
+ for( ; i < ipx->ipx_tctrl ; i++ )
+ if( *l++ == intrfc->if_netnum )
+ break;
+
+ if( i == ipx->ipx_tctrl ) { /* < 8 hops && input itfc not in list */
+ *l = intrfc->if_netnum; /* insert recvd netnum into list */
+
+ /* xmit on all other interfaces... */
+ for ( ifcs = ipx_interfaces; ifcs != NULL ; ifcs = ifcs->if_next) {
+ /* that aren't in the list */
+ l = (long *) c;
+ for( i = 0 ; i <= ipx->ipx_tctrl ; i++ )
+ if( ifcs->if_netnum == *l++ )
+ break;
+ if( i - 1 == ipx->ipx_tctrl ) {
+ ipx->ipx_dest.net = ifcs->if_netnum;
+#ifdef DEBUG_IPX_PPROP_ROUTING
+ printk( "IPX: Forward PPROP onto net num %08x\n", (unsigned int) htonl(ifcs->if_netnum) );
+#endif
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ ipxrtr_route_skb(skb2);
+ }
+#ifdef DEBUG_IPX_PPROP_ROUTING
+ else
+ printk( "IPX: Ignoring PPROP for net num %08x\n", (unsigned int) htonl(ifcs->if_netnum) );
+#endif
+ }
+ /* reset netnum in packet */
+ ipx->ipx_dest.net = intrfc->if_netnum;
+ }
+
+ }
+#endif
+
if (ipx->ipx_dest.net == 0L)
ipx->ipx_dest.net = intrfc->if_netnum;
if (ipx->ipx_source.net == 0L)
@@ -1275,7 +1337,7 @@
* Route an outgoing frame from a socket.
*/
-static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock)
+static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock)
{
struct sk_buff *skb;
ipx_interface *intrfc;
@@ -1309,7 +1371,6 @@
return err;
skb_reserve(skb,ipx_offset);
- skb->free=1;
skb->arp=1;
skb->sk=sk;
@@ -1496,7 +1557,7 @@
static int ipx_get_info(char *buffer, char **start, off_t offset,
int length, int dummy)
{
- ipx_socket *s;
+ struct sock *s;
ipx_interface *i;
int len=0;
off_t pos=0;
@@ -1626,10 +1687,10 @@
static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
{
- ipx_socket *sk;
+ struct sock *sk;
int err,opt;
- sk=(ipx_socket *)sock->data;
+ sk=sock->sk;
if (optval==NULL)
return(-EINVAL);
@@ -1651,9 +1712,6 @@
}
break;
- case SOL_SOCKET:
- return sock_setsockopt(sk,level,optname,optval,optlen);
-
default:
return -EOPNOTSUPP;
}
@@ -1662,11 +1720,11 @@
static int ipx_getsockopt(struct socket *sock, int level, int optname,
char *optval, int *optlen)
{
- ipx_socket *sk;
+ struct sock *sk;
int val=0;
int err;
- sk=(ipx_socket *)sock->data;
+ sk=sock->sk;
switch(level)
{
@@ -1682,9 +1740,6 @@
}
break;
- case SOL_SOCKET:
- return sock_getsockopt(sk,level,optname,optval,optlen);
-
default:
return -EOPNOTSUPP;
}
@@ -1716,16 +1771,17 @@
static int ipx_create(struct socket *sock, int protocol)
{
- ipx_socket *sk;
- sk=(ipx_socket *)sk_alloc(GFP_KERNEL);
+ struct sock *sk;
+ sk=sk_alloc(GFP_KERNEL);
if(sk==NULL)
return(-ENOMEM);
switch(sock->type)
{
case SOCK_DGRAM:
+ sock->ops = &ipx_dgram_ops;
break;
default:
- kfree_s((void *)sk,sizeof(*sk));
+ sk_free(sk);
return(-ESOCKTNOSUPPORT);
}
sk->rcvbuf=SK_RMEM_MAX;
@@ -1742,8 +1798,8 @@
sk->no_check = 1; /* Checksum off by default */
if(sock!=NULL)
{
- sock->data=(void *)sk;
- sk->sleep=sock->wait;
+ sk->sleep=&sock->wait;
+ sock->sk=sk;
}
sk->state_change=def_callback1;
@@ -1758,13 +1814,13 @@
static int ipx_release(struct socket *sock, struct socket *peer)
{
- ipx_socket *sk=(ipx_socket *)sock->data;
+ struct sock *sk=sock->sk;
if(sk==NULL)
return(0);
if(!sk->dead)
sk->state_change(sk);
sk->dead=1;
- sock->data=NULL;
+ sock->sk=NULL;
ipx_destroy_socket(sk);
return(0);
}
@@ -1794,11 +1850,11 @@
static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
- ipx_socket *sk;
+ struct sock *sk;
ipx_interface *intrfc;
struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
- sk=(ipx_socket *)sock->data;
+ sk=sock->sk;
if(sk->zapped==0)
return -EINVAL;
@@ -1895,7 +1951,7 @@
static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{
- ipx_socket *sk=(ipx_socket *)sock->data;
+ struct sock *sk=sock->sk;
struct sockaddr_ipx *addr;
sk->state = TCP_CLOSE;
@@ -1941,8 +1997,8 @@
static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
{
- if(newsock->data) {
- kfree_s(newsock->data,sizeof(ipx_socket));
+ if(newsock->sk) {
+ sk_free(newsock->sk);
MOD_DEC_USE_COUNT;
}
return -EOPNOTSUPP;
@@ -1953,9 +2009,9 @@
{
ipx_address *addr;
struct sockaddr_ipx sipx;
- ipx_socket *sk;
+ struct sock *sk;
- sk=(ipx_socket *)sock->data;
+ sk=sock->sk;
*uaddr_len = sizeof(struct sockaddr_ipx);
@@ -2052,7 +2108,6 @@
ipx_interface *intrfc;
ipx_packet *ipx;
-
ipx=(ipx_packet *)skb->h.raw;
/* Too small */
@@ -2091,19 +2146,20 @@
return ipxitf_rcv(intrfc, skb);
}
-static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, int noblock,
- int flags)
+static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
+ struct scm_cookie *scm)
{
- ipx_socket *sk=(ipx_socket *)sock->data;
+ struct sock *sk=sock->sk;
struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name;
struct sockaddr_ipx local_sipx;
int retval;
+ int flags = msg->msg_flags;
if (sk->zapped)
return -EIO; /* Socket not bound */
- if(flags)
+ if (flags&~MSG_DONTWAIT)
return -EINVAL;
-
+
if(usipx)
{
if(sk->protinfo.af_ipx.port == 0)
@@ -2139,7 +2195,7 @@
memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
}
- retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, noblock);
+ retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, flags&MSG_DONTWAIT);
if (retval < 0)
return retval;
@@ -2147,28 +2203,24 @@
}
-static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock,
- int flags, int *addr_len)
+static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size,
+ int flags, struct scm_cookie *scm)
{
- ipx_socket *sk=(ipx_socket *)sock->data;
+ struct sock *sk=sock->sk;
struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)msg->msg_name;
struct ipx_packet *ipx = NULL;
int copied = 0;
int truesize;
struct sk_buff *skb;
int err;
-
+
if (sk->zapped)
return -ENOTCONN;
-
- skb=skb_recv_datagram(sk,flags,noblock,&err);
+ skb=skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err);
if(skb==NULL)
return err;
- if(addr_len)
- *addr_len=sizeof(*sipx);
-
ipx = (ipx_packet *)(skb->h.raw);
truesize=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
@@ -2184,6 +2236,8 @@
if (err)
return err;
+ msg->msg_namelen = sizeof(*sipx);
+
if(sipx)
{
sipx->sipx_family=AF_IPX;
@@ -2201,17 +2255,10 @@
return -EOPNOTSUPP;
}
-static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
-{
- ipx_socket *sk=(ipx_socket *)sock->data;
-
- return datagram_select(sk,sel_type,wait);
-}
-
static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
{
long amount=0;
- ipx_socket *sk=(ipx_socket *)sock->data;
+ struct sock *sk=sock->sk;
switch(cmd)
{
@@ -2271,10 +2318,14 @@
return(0);
}
-static struct proto_ops ipx_proto_ops = {
+static struct net_proto_family ipx_family_ops = {
+ AF_IPX,
+ ipx_create
+};
+
+static struct proto_ops ipx_dgram_ops = {
AF_IPX,
- ipx_create,
ipx_dup,
ipx_release,
ipx_bind,
@@ -2282,7 +2333,7 @@
ipx_socketpair,
ipx_accept,
ipx_getname,
- ipx_select,
+ datagram_select,
ipx_ioctl,
ipx_listen,
ipx_shutdown,
@@ -2347,7 +2398,7 @@
void
ipx_proto_init(struct net_proto *pro)
{
- (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
+ (void) sock_register(&ipx_family_ops);
pEII_datalink = make_EII_client();
ipx_dix_packet_type.type=htons(ETH_P_IPX);
@@ -2427,7 +2478,7 @@
destroy_EII_client(pEII_datalink);
pEII_datalink = NULL;
- (void) sock_unregister(ipx_proto_ops.family);
+ (void) sock_unregister(ipx_family_ops.family);
return;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov