Commit 343c5aed authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.66

parent a525572b
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 65 SUBLEVEL = 66
ARCH = i386 ARCH = i386
......
...@@ -1386,7 +1386,7 @@ static int con_write(struct tty_struct * tty, int from_user, ...@@ -1386,7 +1386,7 @@ static int con_write(struct tty_struct * tty, int from_user,
if (currcons == sel_cons) if (currcons == sel_cons)
clear_selection(); clear_selection();
disable_bh(KEYBOARD_BH); disable_bh(CONSOLE_BH);
while (!tty->stopped && count) { while (!tty->stopped && count) {
c = from_user ? get_user(buf) : *buf; c = from_user ? get_user(buf) : *buf;
buf++; n++; count--; buf++; n++; count--;
...@@ -1820,7 +1820,7 @@ static int con_write(struct tty_struct * tty, int from_user, ...@@ -1820,7 +1820,7 @@ static int con_write(struct tty_struct * tty, int from_user,
} }
if (vcmode != KD_GRAPHICS) if (vcmode != KD_GRAPHICS)
set_cursor(currcons); set_cursor(currcons);
enable_bh(KEYBOARD_BH); enable_bh(CONSOLE_BH);
return n; return n;
} }
......
...@@ -376,6 +376,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *regs) ...@@ -376,6 +376,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *regs)
goto end_kbd_intr; goto end_kbd_intr;
} }
do_poke_blanked_console = 1; do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
add_keyboard_randomness(scancode); add_keyboard_randomness(scancode);
tty = ttytab[fg_console]; tty = ttytab[fg_console];
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* chains, new "insert" and "append" * chains, new "insert" and "append"
* commands to replace "add" commands, * commands to replace "add" commands,
* add ICMP header to struct ip_fwpkt. * add ICMP header to struct ip_fwpkt.
* Jos Vos : Add support for matching device names.
* *
* All the real work was done by ..... * All the real work was done by .....
*/ */
...@@ -55,6 +56,7 @@ struct ip_fw ...@@ -55,6 +56,7 @@ struct ip_fw
struct in_addr fw_src, fw_dst; /* Source and destination IP addr */ struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */ struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
struct in_addr fw_via; /* IP address of interface "via" */ struct in_addr fw_via; /* IP address of interface "via" */
struct device *fw_viadev; /* device of interface "via" */
unsigned short fw_flg; /* Flags word */ unsigned short fw_flg; /* Flags word */
unsigned short fw_nsp, fw_ndp; /* N'of src ports and # of dst ports */ unsigned short fw_nsp, fw_ndp; /* N'of src ports and # of dst ports */
/* in ports array (dst ports follow */ /* in ports array (dst ports follow */
...@@ -64,6 +66,7 @@ struct ip_fw ...@@ -64,6 +66,7 @@ struct ip_fw
unsigned short fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */ unsigned short fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
unsigned long fw_pcnt,fw_bcnt; /* Packet and byte counters */ unsigned long fw_pcnt,fw_bcnt; /* Packet and byte counters */
unsigned char fw_tosand, fw_tosxor; /* Revised packet priority */ unsigned char fw_tosand, fw_tosxor; /* Revised packet priority */
char fw_vianame[IFNAMSIZ]; /* name of interface "via" */
}; };
/* /*
...@@ -112,6 +115,7 @@ struct ip_fw ...@@ -112,6 +115,7 @@ struct ip_fw
#define IP_FW_IN 1 #define IP_FW_IN 1
#define IP_FW_OUT 2 #define IP_FW_OUT 2
#define IP_FW_ACCT 3 #define IP_FW_ACCT 3
#define IP_FW_CHAINS 4 /* total number of ip_fw chains */
#define IP_FW_INSERT (IP_FW_BASE_CTL) #define IP_FW_INSERT (IP_FW_BASE_CTL)
#define IP_FW_APPEND (IP_FW_BASE_CTL+1) #define IP_FW_APPEND (IP_FW_BASE_CTL+1)
...@@ -160,6 +164,7 @@ struct ip_fwpkt ...@@ -160,6 +164,7 @@ struct ip_fwpkt
struct icmphdr fwp_icmph; /* ICMP header */ struct icmphdr fwp_icmph; /* ICMP header */
} fwp_protoh; } fwp_protoh;
struct in_addr fwp_via; /* interface address */ struct in_addr fwp_via; /* interface address */
char fwp_vianame[IFNAMSIZ]; /* interface name */
}; };
/* /*
......
...@@ -295,24 +295,33 @@ static char *statename[]={ ...@@ -295,24 +295,33 @@ static char *statename[]={
static __inline__ void tcp_set_state(struct sock *sk, int state) static __inline__ void tcp_set_state(struct sock *sk, int state)
{ {
if(sk->state==TCP_ESTABLISHED) int oldstate = sk->state;
tcp_statistics.TcpCurrEstab--;
sk->state = state;
#ifdef STATE_TRACE #ifdef STATE_TRACE
if(sk->debug) if(sk->debug)
printk("TCP sk=%p, State %s -> %s\n",sk, statename[sk->state],statename[state]); printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
#endif #endif
switch (state) {
case TCP_ESTABLISHED:
if (oldstate != TCP_ESTABLISHED) {
tcp_statistics.TcpCurrEstab++;
/* This is a hack but it doesn't occur often and it's going to /* This is a hack but it doesn't occur often and it's going to
be a real to fix nicely */ be a real to fix nicely */
if (oldstate == TCP_SYN_RECV)
if(state==TCP_ESTABLISHED && sk->state==TCP_SYN_RECV)
{
wake_up_interruptible(&master_select_wakeup); wake_up_interruptible(&master_select_wakeup);
} }
sk->state=state; break;
if(state==TCP_ESTABLISHED)
tcp_statistics.TcpCurrEstab++; case TCP_CLOSE:
if(sk->state==TCP_CLOSE)
tcp_cache_zap(); tcp_cache_zap();
/* fall through */
default:
if (oldstate==TCP_ESTABLISHED)
tcp_statistics.TcpCurrEstab--;
}
} }
#endif /* _TCP_H */ #endif /* _TCP_H */
...@@ -570,8 +570,8 @@ void __release_sock(struct sock *sk) ...@@ -570,8 +570,8 @@ void __release_sock(struct sock *sk)
sk->users = 0; sk->users = 0;
barrier(); barrier();
} }
if (sk->dead && sk->state == TCP_CLOSE)
{ if (sk->dead && sk->state == TCP_CLOSE) {
/* Should be about 2 rtt's */ /* Should be about 2 rtt's */
reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME)); reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
} }
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
* only delete the first matching entry, use 0xFFFF (0xFF) as ports (ICMP * only delete the first matching entry, use 0xFFFF (0xFF) as ports (ICMP
* types) when counting packets being 2nd and further fragments. * types) when counting packets being 2nd and further fragments.
* Jos Vos <jos@xos.nl> 8/2/1996. * Jos Vos <jos@xos.nl> 8/2/1996.
* Add support for matching on device names.
* Jos Vos <jos@xos.nl> 15/2/1996.
* *
* Masquerading functionality * Masquerading functionality
* *
...@@ -363,13 +365,23 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol ...@@ -363,13 +365,23 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol
if (match) if (match)
{ {
/* /*
* Look for a VIA match * Look for a VIA address match
*/ */
if(f->fw_via.s_addr && rif) if(f->fw_via.s_addr && rif)
{ {
if(rif->pa_addr!=f->fw_via.s_addr) if(rif->pa_addr!=f->fw_via.s_addr)
continue; /* Mismatch */ continue; /* Mismatch */
} }
/*
* Look for a VIA device match
*/
if(f->fw_viadev)
{
if(rif!=f->fw_viadev)
continue; /* Mismatch */
}
/* /*
* Drop through - this is a match * Drop through - this is a match
*/ */
...@@ -472,7 +484,7 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol ...@@ -472,7 +484,7 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol
break; break;
} /* Loop */ } /* Loop */
answer = FW_BLOCK; if (opt != 1) {
/* /*
* We rely on policy defined in the rejecting entry or, if no match * We rely on policy defined in the rejecting entry or, if no match
...@@ -480,35 +492,31 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol ...@@ -480,35 +492,31 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol
* of firewall. * of firewall.
*/ */
if(f!=NULL) if (f!=NULL) {
{
policy=f->fw_flg; policy=f->fw_flg;
tosand=f->fw_tosand; tosand=f->fw_tosand;
tosxor=f->fw_tosxor; tosxor=f->fw_tosxor;
} } else {
else
{
tosand=0xFF; tosand=0xFF;
tosxor=0x00; tosxor=0x00;
} }
if(opt != 1) if (policy&IP_FW_F_ACCEPT) {
{ /* Adjust priority and recompute checksum */
if(policy&IP_FW_F_ACCEPT)
answer=(policy&IP_FW_F_MASQ)?FW_MASQUERADE:FW_ACCEPT;
else
if(policy&IP_FW_F_ICMPRPL)
answer = FW_REJECT;
}
if (policy&IP_FW_F_ACCEPT) { /* Adjust priority and recompute checksum */
__u8 old_tos = ip->tos; __u8 old_tos = ip->tos;
ip->tos = (old_tos & tosand) ^ tosxor; ip->tos = (old_tos & tosand) ^ tosxor;
if (ip->tos != old_tos) if (ip->tos != old_tos)
ip_send_check(ip); ip_send_check(ip);
} answer=(policy&IP_FW_F_MASQ)?FW_MASQUERADE:FW_ACCEPT;
} else if(policy&IP_FW_F_ICMPRPL)
answer = FW_REJECT;
else
answer = FW_BLOCK;
return answer; return answer;
} else
/* we're doing accounting, always ok */
return 0;
} }
#ifdef CONFIG_IP_MASQUERADE #ifdef CONFIG_IP_MASQUERADE
...@@ -897,6 +905,7 @@ void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev) ...@@ -897,6 +905,7 @@ void ip_fw_masquerade(struct sk_buff **skb_ptr, struct device *dev)
} }
else ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP; else ms->timer.expires = jiffies+MASQUERADE_EXPIRE_TCP;
skb->csum = csum_partial(th + 1, size - sizeof(*th), 0);
tcp_send_check(th,iph->saddr,iph->daddr,size,skb); tcp_send_check(th,iph->saddr,iph->daddr,size,skb);
} }
add_timer(&ms->timer); add_timer(&ms->timer);
...@@ -1002,6 +1011,8 @@ int ip_fw_demasquerade(struct sk_buff *skb) ...@@ -1002,6 +1011,8 @@ int ip_fw_demasquerade(struct sk_buff *skb)
#endif #endif
} }
} }
skb->csum = csum_partial(portptr + sizeof(struct tcphdr),
size - sizeof(struct tcphdr), 0);
tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb); tcp_send_check((struct tcphdr *)portptr,iph->saddr,iph->daddr,size,skb);
} }
ip_send_check(iph); ip_send_check(iph);
...@@ -1072,6 +1083,12 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl, ...@@ -1072,6 +1083,12 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
cli(); cli();
if ((ftmp->fw_vianame)[0]) {
if (!(ftmp->fw_viadev = dev_get(ftmp->fw_vianame)))
ftmp->fw_viadev = (struct device *) -1;
} else
ftmp->fw_viadev = NULL;
ftmp->fw_next = *chainptr; ftmp->fw_next = *chainptr;
*chainptr=ftmp; *chainptr=ftmp;
restore_flags(flags); restore_flags(flags);
...@@ -1106,6 +1123,12 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl, ...@@ -1106,6 +1123,12 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
cli(); cli();
if ((ftmp->fw_vianame)[0]) {
if (!(ftmp->fw_viadev = dev_get(ftmp->fw_vianame)))
ftmp->fw_viadev = (struct device *) -1;
} else
ftmp->fw_viadev = NULL;
chtmp_prev=NULL; chtmp_prev=NULL;
for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next) for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
chtmp_prev=chtmp; chtmp_prev=chtmp;
...@@ -1163,6 +1186,8 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl) ...@@ -1163,6 +1186,8 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum]) if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
matches=0; matches=0;
} }
if (strncmp(ftmp->fw_vianame, frwl->fw_vianame, IFNAMSIZ))
matches=0;
if(matches) if(matches)
{ {
was_found=1; was_found=1;
...@@ -1332,11 +1357,11 @@ int ip_fw_ctl(int stage, void *m, int len) ...@@ -1332,11 +1357,11 @@ int ip_fw_ctl(int stage, void *m, int len)
if ( cmd == IP_FW_CHECK ) if ( cmd == IP_FW_CHECK )
{ {
struct device viadev; struct device *viadev;
struct ip_fwpkt *ipfwp; struct ip_fwpkt *ipfwp;
struct iphdr *ip; struct iphdr *ip;
if ( len < sizeof(struct ip_fwpkt) ) if ( len != sizeof(struct ip_fwpkt) )
{ {
#ifdef DEBUG_CONFIG_IP_FIREWALL #ifdef DEBUG_CONFIG_IP_FIREWALL
printk("ip_fw_ctl: length=%d, expected %d\n", printk("ip_fw_ctl: length=%d, expected %d\n",
...@@ -1348,8 +1373,18 @@ int ip_fw_ctl(int stage, void *m, int len) ...@@ -1348,8 +1373,18 @@ int ip_fw_ctl(int stage, void *m, int len)
ipfwp = (struct ip_fwpkt *)m; ipfwp = (struct ip_fwpkt *)m;
ip = &(ipfwp->fwp_iph); ip = &(ipfwp->fwp_iph);
if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) if ( !(viadev = dev_get(ipfwp->fwp_vianame)) ) {
{ #ifdef DEBUG_CONFIG_IP_FIREWALL
printk("ip_fw_ctl: invalid device \"%s\"\n", ipfwp->fwp_vianame);
#endif
return(EINVAL);
} else if ( viadev->pa_addr != ipfwp->fwp_via.s_addr ) {
#ifdef DEBUG_CONFIG_IP_FIREWALL
printk("ip_fw_ctl: device \"%s\" has another IP address\n",
ipfwp->fwp_vianame);
#endif
return(EINVAL);
} else if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
#ifdef DEBUG_CONFIG_IP_FIREWALL #ifdef DEBUG_CONFIG_IP_FIREWALL
printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl, printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
sizeof(struct iphdr)/sizeof(int)); sizeof(struct iphdr)/sizeof(int));
...@@ -1357,9 +1392,7 @@ int ip_fw_ctl(int stage, void *m, int len) ...@@ -1357,9 +1392,7 @@ int ip_fw_ctl(int stage, void *m, int len)
return(EINVAL); return(EINVAL);
} }
viadev.pa_addr = ipfwp->fwp_via.s_addr; if ((ret = ip_fw_chk(ip, viadev, *chains[fwtype],
if ((ret = ip_fw_chk(ip, &viadev, *chains[fwtype],
*policies[fwtype], 2)) == FW_ACCEPT) *policies[fwtype], 2)) == FW_ACCEPT)
return(0); return(0);
else if (ret == FW_MASQUERADE) else if (ret == FW_MASQUERADE)
...@@ -1459,9 +1492,10 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start, ...@@ -1459,9 +1492,10 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start,
while(i!=NULL) while(i!=NULL)
{ {
len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %08lX %X ", len+=sprintf(buffer+len,"%08lX/%08lX->%08lX/%08lX %.16s %08lX %X ",
ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr), ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr), ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
(i->fw_vianame)[0] ? i->fw_vianame : "-",
ntohl(i->fw_via.s_addr),i->fw_flg); ntohl(i->fw_via.s_addr),i->fw_flg);
len+=sprintf(buffer+len,"%u %u %-9lu %-9lu", len+=sprintf(buffer+len,"%u %u %-9lu %-9lu",
i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt); i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
...@@ -1611,6 +1645,46 @@ struct firewall_ops ipfw_ops= ...@@ -1611,6 +1645,46 @@ struct firewall_ops ipfw_ops=
#endif #endif
#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
int ipfw_device_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct device *dev=ptr;
char *devname = dev->name;
unsigned long flags;
struct ip_fw *fw;
int chn;
save_flags(flags);
cli();
if (event == NETDEV_UP) {
for (chn = 0; chn < IP_FW_CHAINS; chn++)
for (fw = *chains[chn]; fw; fw = fw->fw_next)
if ((fw->fw_vianame)[0] && !strncmp(devname,
fw->fw_vianame, IFNAMSIZ))
fw->fw_viadev = dev;
} else if (event == NETDEV_DOWN) {
for (chn = 0; chn < IP_FW_CHAINS; chn++)
for (fw = *chains[chn]; fw; fw = fw->fw_next)
/* we could compare just the pointers ... */
if ((fw->fw_vianame)[0] && !strncmp(devname,
fw->fw_vianame, IFNAMSIZ))
fw->fw_viadev = (struct device *) -1;
}
restore_flags(flags);
return NOTIFY_DONE;
}
static struct notifier_block ipfw_dev_notifier={
ipfw_device_event,
NULL,
0
};
#endif
void ip_fw_init(void) void ip_fw_init(void)
{ {
#ifdef CONFIG_IP_ACCT #ifdef CONFIG_IP_ACCT
...@@ -1653,4 +1727,8 @@ void ip_fw_init(void) ...@@ -1653,4 +1727,8 @@ void ip_fw_init(void)
ip_msqhst_procinfo ip_msqhst_procinfo
}); });
#endif #endif
#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
/* Register for device up/down reports */
register_netdevice_notifier(&ipfw_dev_notifier);
#endif
} }
...@@ -1929,6 +1929,15 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -1929,6 +1929,15 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
if(tcp_data(skb,sk, saddr, len)) if(tcp_data(skb,sk, saddr, len))
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
/*
* Finally, if we've moved to TCP_CLOSE, check if we should
* get rid of the socket
*/
if (sk->dead && sk->state == TCP_CLOSE) {
/* Should be about 2 rtt's */
reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
}
/* /*
* And done * And done
*/ */
......
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