Commit de0eab26 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.6

parent 37b4c9bd
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 5 SUBLEVEL = 6
all: Version zImage all: Version zImage
......
...@@ -201,9 +201,10 @@ static unsigned int d_link_debug = D_LINK_DEBUG; ...@@ -201,9 +201,10 @@ static unsigned int d_link_debug = D_LINK_DEBUG;
/* /*
* Index to functions, as function prototypes. * Index to functions, as function prototypes.
*/ */
#if 0
/* For tricking tcp.c to announce a small max window (max 2 fast packets please :-) */ /* For tricking tcp.c to announce a small max window (max 2 fast packets please :-) */
static unsigned long d_link_rspace(struct sock *sk); static unsigned long d_link_rspace(struct sock *sk);
#endif
/* Routines used internally. (See "convenience macros") */ /* Routines used internally. (See "convenience macros") */
static int d_link_read_status(struct device *dev); static int d_link_read_status(struct device *dev);
...@@ -689,6 +690,10 @@ adapter_init(struct device *dev) ...@@ -689,6 +690,10 @@ adapter_init(struct device *dev)
sti(); sti();
} }
#if 0
/*
* The new router code (coming soon 8-) ) will fix this properly.
*/
#define D_LINK_MIN_WINDOW 1024 #define D_LINK_MIN_WINDOW 1024
#define D_LINK_MAX_WINDOW 2048 #define D_LINK_MAX_WINDOW 2048
#define D_LINK_TCP_WINDOW_DIFF 1024 #define D_LINK_TCP_WINDOW_DIFF 1024
...@@ -724,3 +729,6 @@ d_link_rspace(struct sock *sk) ...@@ -724,3 +729,6 @@ d_link_rspace(struct sock *sk)
} }
return(0); return(0);
} }
#endif
...@@ -644,32 +644,7 @@ depca_probe1(struct device *dev, short ioaddr) ...@@ -644,32 +644,7 @@ depca_probe1(struct device *dev, short ioaddr)
dev->mem_start = 0; dev->mem_start = 0;
/* Fill in the generic field of the device structure. */ /* Fill in the generic field of the device structure. */
for (i = 0; i < DEV_NUMBUFFS; i++) { ether_setup(dev);
dev->buffs[i] = NULL;
}
dev->hard_header = eth_header;
dev->add_arp = eth_add_arp;
dev->queue_xmit = dev_queue_xmit;
dev->rebuild_header = eth_rebuild_header;
dev->type_trans = eth_type_trans;
dev->type = ARPHRD_ETHER;
dev->hard_header_len = ETH_HLEN;
dev->mtu = 1500; /* eth_mtu */
dev->addr_len = ETH_ALEN;
for (i = 0; i < dev->addr_len; i++) {
dev->broadcast[i]=0xff;
}
/* New-style flags. */
dev->flags = IFF_BROADCAST;
dev->family = AF_INET;
dev->pa_addr = 0;
dev->pa_brdaddr = 0;
dev->pa_mask = 0;
dev->pa_alen = sizeof(unsigned long);
} }
} else { } else {
status = -ENXIO; status = -ENXIO;
...@@ -832,14 +807,6 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev) ...@@ -832,14 +807,6 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev)
return 0; return 0;
} }
/* Fill in the ethernet header. */
if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
skb->dev = dev;
arp_queue (skb);
return 0;
}
skb->arp=1;
if (skb->len <= 0) { if (skb->len <= 0) {
return 0; return 0;
} }
......
...@@ -1030,6 +1030,12 @@ int sl_set_mac_address(struct device *dev, void *addr) ...@@ -1030,6 +1030,12 @@ int sl_set_mac_address(struct device *dev, void *addr)
memcpy_fromfs(dev->dev_addr,addr,7); /* addr is an AX.25 shifted ASCII mac address */ memcpy_fromfs(dev->dev_addr,addr,7); /* addr is an AX.25 shifted ASCII mac address */
return 0; return 0;
} }
static int sl_set_dev_mac_address(struct device *dev, void *addr)
{
memcpy(dev->dev_addr,addr,7);
return 0;
}
#endif #endif
...@@ -1144,7 +1150,7 @@ slip_init(struct device *dev) ...@@ -1144,7 +1150,7 @@ slip_init(struct device *dev)
dev->get_stats = sl_get_stats; dev->get_stats = sl_get_stats;
#ifdef HAVE_SET_MAC_ADDR #ifdef HAVE_SET_MAC_ADDR
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
dev->set_mac_address = sl_set_mac_address; dev->set_mac_address = sl_set_dev_mac_address;
#endif #endif
#endif #endif
dev->hard_header_len = 0; dev->hard_header_len = 0;
......
...@@ -68,7 +68,7 @@ struct sk_buff { ...@@ -68,7 +68,7 @@ struct sk_buff {
used, used,
free, free,
arp; arp;
unsigned char tries,lock; unsigned char tries,lock,localroute;
unsigned short users; /* User count - see datagram.c (and soon seqpacket.c/stream.c) */ unsigned short users; /* User count - see datagram.c (and soon seqpacket.c/stream.c) */
unsigned long padding[0]; unsigned long padding[0];
unsigned char data[0]; unsigned char data[0];
......
...@@ -42,6 +42,7 @@ struct linger { ...@@ -42,6 +42,7 @@ struct linger {
/* Flags we can use with send/ and recv. */ /* Flags we can use with send/ and recv. */
#define MSG_OOB 1 #define MSG_OOB 1
#define MSG_PEEK 2 #define MSG_PEEK 2
#define MSG_DONTROUTE 4
/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
#define SOL_SOCKET 1 #define SOL_SOCKET 1
......
...@@ -364,17 +364,6 @@ NORET_TYPE void do_exit(long code) ...@@ -364,17 +364,6 @@ NORET_TYPE void do_exit(long code)
sem_exit(); sem_exit();
if (current->shm) if (current->shm)
shm_exit(); shm_exit();
free_page_tables(current);
for (i=0 ; i<NR_OPEN ; i++)
if (current->filp[i])
sys_close(i);
forget_original_parent(current);
iput(current->pwd);
current->pwd = NULL;
iput(current->root);
current->root = NULL;
iput(current->executable);
current->executable = NULL;
/* Release all of the old mmap stuff. */ /* Release all of the old mmap stuff. */
{ {
...@@ -390,17 +379,28 @@ NORET_TYPE void do_exit(long code) ...@@ -390,17 +379,28 @@ NORET_TYPE void do_exit(long code)
} }
} }
/* forget local segments */
__asm__ __volatile__("mov %w0,%%fs ; mov %w0,%%gs ; lldt %w0"
: /* no outputs */
: "r" (0));
current->tss.ldt = 0;
if (current->ldt) { if (current->ldt) {
vfree(current->ldt); void * ldt = current->ldt;
current->ldt = NULL; current->ldt = NULL;
for (i=1 ; i<NR_TASKS ; i++) { vfree(ldt);
if (task[i] == current) {
set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, &default_ldt, 1);
load_ldt(i);
}
}
} }
free_page_tables(current);
for (i=0 ; i<NR_OPEN ; i++)
if (current->filp[i])
sys_close(i);
forget_original_parent(current);
iput(current->pwd);
current->pwd = NULL;
iput(current->root);
current->root = NULL;
iput(current->executable);
current->executable = NULL;
/* /*
* Check to see if any process groups have become orphaned * Check to see if any process groups have become orphaned
* as a result of our exiting, and if they have any stopped * as a result of our exiting, and if they have any stopped
......
...@@ -549,7 +549,7 @@ void dev_transmit(void) ...@@ -549,7 +549,7 @@ void dev_transmit(void)
for (dev = dev_base; dev != NULL; dev = dev->next) for (dev = dev_base; dev != NULL; dev = dev->next)
{ {
if (!dev->tbusy) { if (dev->flags != 0 && !dev->tbusy) {
/* /*
* Kick the device * Kick the device
*/ */
......
...@@ -284,6 +284,9 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd ...@@ -284,6 +284,9 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd
if (*dev == NULL) if (*dev == NULL)
{ {
if(skb->localroute)
rt = ip_rt_local(daddr, &optmem, &src);
else
rt = ip_rt_route(daddr, &optmem, &src); rt = ip_rt_route(daddr, &optmem, &src);
if (rt == NULL) if (rt == NULL)
{ {
...@@ -308,6 +311,9 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd ...@@ -308,6 +311,9 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd
/* /*
* We still need the address of the first hop. * We still need the address of the first hop.
*/ */
if(skb->localroute)
rt = ip_rt_local(daddr, &optmem, &src);
else
rt = ip_rt_route(daddr, &optmem, &src); rt = ip_rt_route(daddr, &optmem, &src);
/* /*
* If the frame is from us and going off machine it MUST MUST MUST * If the frame is from us and going off machine it MUST MUST MUST
......
...@@ -503,6 +503,7 @@ static int ipx_create(struct socket *sock, int protocol) ...@@ -503,6 +503,7 @@ static int ipx_create(struct socket *sock, int protocol)
sk->type=sock->type; sk->type=sock->type;
sk->ipx_type=0; /* General user level IPX */ sk->ipx_type=0; /* General user level IPX */
sk->debug=0; sk->debug=0;
sk->localroute=0;
memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr)); memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
memset(&sk->ipx_source_addr,'\0',sizeof(sk->ipx_source_addr)); memset(&sk->ipx_source_addr,'\0',sizeof(sk->ipx_source_addr));
...@@ -836,7 +837,7 @@ static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock, ...@@ -836,7 +837,7 @@ static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
int size; int size;
ipx_route *rt; ipx_route *rt;
if(flags) if(flags&~MSG_DONTROUTE)
return -EINVAL; return -EINVAL;
if(len<0) if(len<0)
return -EINVAL; return -EINVAL;
...@@ -882,7 +883,8 @@ static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock, ...@@ -882,7 +883,8 @@ static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
/* Find out where this has to go */ /* Find out where this has to go */
rt=ipxrtr_get_dev(sipx.sipx_network); rt=ipxrtr_get_dev(sipx.sipx_network);
if(rt==NULL) /* No suitable route - no gateways when not routing */
if(rt==NULL || ((flags&IPX_RT_ROUTED)&& ((flags&MSG_DONTROUTE)||sk->localroute)))
{ {
return -ENETUNREACH; return -ENETUNREACH;
} }
...@@ -917,7 +919,7 @@ static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock, ...@@ -917,7 +919,7 @@ static int ipx_sendto(struct socket *sock, void *ubuf, int len, int noblock,
skb->dev=rt->dev; skb->dev=rt->dev;
dev->hard_header(skb->data,skb->dev, dev->hard_header(skb->data,skb->dev,
(rt->flags&IPX_RT_BLUEBOOK)?ntohs(ETH_P_IPX):ntohs(len+sizeof(ipx_packet)), (rt->flags&IPX_RT_BLUEBOOK)?ETH_P_IPX:ETH_P_802_3),
(rt->flags&IPX_RT_ROUTED)?rt->router_node:sipx.sipx_node, (rt->flags&IPX_RT_ROUTED)?rt->router_node:sipx.sipx_node,
NULL, NULL,
len+sizeof(ipx_packet), len+sizeof(ipx_packet),
......
...@@ -142,12 +142,12 @@ raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -142,12 +142,12 @@ raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
return(0); return(0);
} }
/*
* Send a RAW IP packet.
*/
/* This will do terrible things if len + ipheader + devheader > dev->mtu */ static int raw_sendto(struct sock *sk, unsigned char *from,
static int int len, int noblock, unsigned flags, struct sockaddr_in *usin, int addr_len)
raw_sendto(struct sock *sk, unsigned char *from, int len,
int noblock,
unsigned flags, struct sockaddr_in *usin, int addr_len)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct device *dev=NULL; struct device *dev=NULL;
...@@ -159,35 +159,51 @@ raw_sendto(struct sock *sk, unsigned char *from, int len, ...@@ -159,35 +159,51 @@ raw_sendto(struct sock *sk, unsigned char *from, int len,
" usin=%X, addr_len = %d)\n", sk, from, len, noblock, " usin=%X, addr_len = %d)\n", sk, from, len, noblock,
flags, usin, addr_len)); flags, usin, addr_len));
/* Check the flags. */ /*
if (flags) return(-EINVAL); * Check the flags. Only MSG_DONTROUTE is permitted.
if (len < 0) return(-EINVAL); */
if (flags&MSG_DONTROUTE)
return(-EINVAL);
if (len < 0)
return(-EINVAL);
err=verify_area(VERIFY_READ,from,len); err=verify_area(VERIFY_READ,from,len);
if(err) if(err)
return err; return err;
/* Get and verify the address. */ /*
if (usin) { * Get and verify the address.
if (addr_len < sizeof(sin)) return(-EINVAL); */
if (usin)
{
if (addr_len < sizeof(sin))
return(-EINVAL);
err=verify_area (VERIFY_READ, usin, sizeof (sin)); err=verify_area (VERIFY_READ, usin, sizeof (sin));
if(err) if(err)
return err; return err;
memcpy_fromfs(&sin, usin, sizeof(sin)); memcpy_fromfs(&sin, usin, sizeof(sin));
if (sin.sin_family && sin.sin_family != AF_INET) return(-EINVAL); if (sin.sin_family && sin.sin_family != AF_INET)
} else { return(-EINVAL);
if (sk->state != TCP_ESTABLISHED) return(-EINVAL); }
else
{
if (sk->state != TCP_ESTABLISHED)
return(-EINVAL);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = sk->protocol; sin.sin_port = sk->protocol;
sin.sin_addr.s_addr = sk->daddr; sin.sin_addr.s_addr = sk->daddr;
} }
if (sin.sin_port == 0) sin.sin_port = sk->protocol; if (sin.sin_port == 0)
sin.sin_port = sk->protocol;
if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST) if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
return -EACCES; return -EACCES;
sk->inuse = 1; sk->inuse = 1;
skb = NULL; skb = NULL;
while (skb == NULL) { while (skb == NULL)
{
if(sk->err!=0) if(sk->err!=0)
{ {
err= -sk->err; err= -sk->err;
...@@ -199,7 +215,8 @@ raw_sendto(struct sock *sk, unsigned char *from, int len, ...@@ -199,7 +215,8 @@ raw_sendto(struct sock *sk, unsigned char *from, int len,
skb = sk->prot->wmalloc(sk, skb = sk->prot->wmalloc(sk,
len + sk->prot->max_header, len + sk->prot->max_header,
0, GFP_KERNEL); 0, GFP_KERNEL);
if (skb == NULL) { if (skb == NULL)
{
int tmp; int tmp;
DPRINTF((DBG_RAW, "raw_sendto: write buffer full?\n")); DPRINTF((DBG_RAW, "raw_sendto: write buffer full?\n"));
...@@ -220,31 +237,35 @@ raw_sendto(struct sock *sk, unsigned char *from, int len, ...@@ -220,31 +237,35 @@ raw_sendto(struct sock *sk, unsigned char *from, int len,
} }
} }
skb->sk = sk; skb->sk = sk;
skb->free = 1; skb->free = 1;
skb->localroute = sk->localroute | (flags&MSG_DONTROUTE);
tmp = sk->prot->build_header(skb, sk->saddr, tmp = sk->prot->build_header(skb, sk->saddr,
sin.sin_addr.s_addr, &dev, sin.sin_addr.s_addr, &dev,
sk->protocol, sk->opt, skb->mem_len, sk->ip_tos,sk->ip_ttl); sk->protocol, sk->opt, skb->mem_len, sk->ip_tos,sk->ip_ttl);
if (tmp < 0) { if (tmp < 0)
{
DPRINTF((DBG_RAW, "raw_sendto: error building ip header.\n")); DPRINTF((DBG_RAW, "raw_sendto: error building ip header.\n"));
kfree_skb(skb,FREE_WRITE); kfree_skb(skb,FREE_WRITE);
release_sock(sk); release_sock(sk);
return(tmp); return(tmp);
} }
/* verify_area(VERIFY_WRITE, from, len);*/
memcpy_fromfs(skb->data + tmp, from, len); memcpy_fromfs(skb->data + tmp, from, len);
/* If we are using IPPROTO_RAW, we need to fill in the source address in /*
the IP header */ * If we are using IPPROTO_RAW, we need to fill in the source address in
* the IP header
*/
if(sk->protocol==IPPROTO_RAW) { if(sk->protocol==IPPROTO_RAW)
{
unsigned char *buff; unsigned char *buff;
struct iphdr *iph; struct iphdr *iph;
buff = skb->data; buff = skb->data;
buff += tmp; buff += tmp;
iph = (struct iphdr *)buff; iph = (struct iphdr *)buff;
iph->saddr = sk->saddr; iph->saddr = sk->saddr;
} }
...@@ -257,16 +278,14 @@ raw_sendto(struct sock *sk, unsigned char *from, int len, ...@@ -257,16 +278,14 @@ raw_sendto(struct sock *sk, unsigned char *from, int len,
} }
static int static int raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
unsigned flags) unsigned flags)
{ {
return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0)); return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
} }
static void static void raw_close(struct sock *sk, int timeout)
raw_close(struct sock *sk, int timeout)
{ {
sk->inuse = 1; sk->inuse = 1;
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
......
...@@ -573,6 +573,42 @@ struct rtable * ip_rt_route(unsigned long daddr, struct options *opt, unsigned l ...@@ -573,6 +573,42 @@ struct rtable * ip_rt_route(unsigned long daddr, struct options *opt, unsigned l
return NULL; return NULL;
} }
struct rtable * ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr)
{
struct rtable *rt;
for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next)
{
/*
* No routed addressing.
*/
if (rt->rt_flags&RTF_GATEWAY)
continue;
if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
break;
/*
* broadcast addresses can be special cases..
*/
if ((rt->rt_dev->flags & IFF_BROADCAST) &&
rt->rt_dev->pa_brdaddr == daddr)
break;
}
if(src_addr!=NULL)
*src_addr= rt->rt_dev->pa_addr;
if (daddr == rt->rt_dev->pa_addr) {
if ((rt = rt_loopback) == NULL)
goto no_route;
}
rt->rt_use++;
return rt;
no_route:
return NULL;
}
/* /*
* Backwards compatibility * Backwards compatibility
*/ */
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Fixes:
* Alan Cox : Reformatted. Added ip_rt_local()
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -23,7 +25,8 @@ ...@@ -23,7 +25,8 @@
/* This is an entry in the IP routing table. */ /* This is an entry in the IP routing table. */
struct rtable { struct rtable
{
struct rtable *rt_next; struct rtable *rt_next;
unsigned long rt_dst; unsigned long rt_dst;
unsigned long rt_mask; unsigned long rt_mask;
...@@ -41,6 +44,7 @@ extern void ip_rt_flush(struct device *dev); ...@@ -41,6 +44,7 @@ extern void ip_rt_flush(struct device *dev);
extern void ip_rt_add(short flags, unsigned long addr, unsigned long mask, extern void ip_rt_add(short flags, unsigned long addr, unsigned long mask,
unsigned long gw, struct device *dev); unsigned long gw, struct device *dev);
extern struct rtable *ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr); extern struct rtable *ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr);
extern struct rtable *ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr);
extern int rt_get_info(char * buffer, char **start, off_t offset, int length); extern int rt_get_info(char * buffer, char **start, off_t offset, int length);
extern int ip_rt_ioctl(unsigned int cmd, void *arg); extern int ip_rt_ioctl(unsigned int cmd, void *arg);
......
...@@ -489,7 +489,8 @@ int sock_setsockopt(struct sock *sk, int level, int optname, ...@@ -489,7 +489,8 @@ int sock_setsockopt(struct sock *sk, int level, int optname,
case SO_DEBUG: case SO_DEBUG:
sk->debug=val?1:0; sk->debug=val?1:0;
case SO_DONTROUTE: /* Still to be implemented */ case SO_DONTROUTE:
sk->localroute=val?1:0;
return(0); return(0);
case SO_BROADCAST: case SO_BROADCAST:
sk->broadcast=val?1:0; sk->broadcast=val?1:0;
...@@ -580,8 +581,8 @@ int sock_getsockopt(struct sock *sk, int level, int optname, ...@@ -580,8 +581,8 @@ int sock_getsockopt(struct sock *sk, int level, int optname,
val = sk->debug; val = sk->debug;
break; break;
case SO_DONTROUTE: /* One last option to implement */ case SO_DONTROUTE:
val = 0; val = sk->localroute;
break; break;
case SO_BROADCAST: case SO_BROADCAST:
...@@ -852,6 +853,7 @@ inet_create(struct socket *sock, int protocol) ...@@ -852,6 +853,7 @@ inet_create(struct socket *sock, int protocol)
sk->send_head = NULL; sk->send_head = NULL;
sk->timeout = 0; sk->timeout = 0;
sk->broadcast = 0; sk->broadcast = 0;
sk->localroute = 0;
sk->timer.data = (unsigned long)sk; sk->timer.data = (unsigned long)sk;
sk->timer.function = &net_timer; sk->timer.function = &net_timer;
skb_queue_head_init(&sk->back_log); skb_queue_head_init(&sk->back_log);
......
...@@ -132,6 +132,7 @@ struct sock { ...@@ -132,6 +132,7 @@ struct sock {
unsigned short rcvbuf; unsigned short rcvbuf;
unsigned short sndbuf; unsigned short sndbuf;
unsigned short type; unsigned short type;
unsigned char localroute; /* Route locally only */
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
ipx_address ipx_source_addr,ipx_dest_addr; ipx_address ipx_source_addr,ipx_dest_addr;
unsigned short ipx_type; unsigned short ipx_type;
......
This diff is collapsed.
...@@ -250,7 +250,7 @@ static void udp_send_check(struct udphdr *uh, unsigned long saddr, ...@@ -250,7 +250,7 @@ static void udp_send_check(struct udphdr *uh, unsigned long saddr,
static int udp_send(struct sock *sk, struct sockaddr_in *sin, static int udp_send(struct sock *sk, struct sockaddr_in *sin,
unsigned char *from, int len) unsigned char *from, int len, int rt)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct device *dev; struct device *dev;
...@@ -281,6 +281,7 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin, ...@@ -281,6 +281,7 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin,
skb->sk = NULL; /* to avoid changing sk->saddr */ skb->sk = NULL; /* to avoid changing sk->saddr */
skb->free = 1; skb->free = 1;
skb->localroute = sk->localroute|(rt&MSG_DONTROUTE);
/* /*
* Now build the IP and MAC header. * Now build the IP and MAC header.
...@@ -357,7 +358,7 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock ...@@ -357,7 +358,7 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock
/* /*
* Check the flags. We support no flags for UDP sending * Check the flags. We support no flags for UDP sending
*/ */
if (flags) if (flags&~MSG_DONTROUTE)
return(-EINVAL); return(-EINVAL);
if (len < 0) if (len < 0)
return(-EINVAL); return(-EINVAL);
...@@ -400,7 +401,7 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock ...@@ -400,7 +401,7 @@ static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock
sk->inuse = 1; sk->inuse = 1;
/* Send the packet. */ /* Send the packet. */
tmp = udp_send(sk, &sin, from, len); tmp = udp_send(sk, &sin, from, len, flags);
/* The datagram has been sent off. Release the socket. */ /* The datagram has been sent off. Release the socket. */
release_sock(sk); release_sock(sk);
...@@ -614,6 +615,8 @@ udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len) ...@@ -614,6 +615,8 @@ udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
memcpy_fromfs(&sin, usin, sizeof(sin)); memcpy_fromfs(&sin, usin, sizeof(sin));
if (sin.sin_family && sin.sin_family != AF_INET) if (sin.sin_family && sin.sin_family != AF_INET)
return(-EAFNOSUPPORT); return(-EAFNOSUPPORT);
if (sin.sin_addr.s_addr==INADDR_ANY)
sin.sin_addr.s_addr=ip_my_addr();
if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST) if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
return -EACCES; /* Must turn broadcast on first */ return -EACCES; /* Must turn broadcast on first */
......
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