diff options
Diffstat (limited to 'include/net')
44 files changed, 2950 insertions, 1101 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 03f9982bd..6a9c00c2a 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -38,9 +38,11 @@ struct prefix_info { #include <linux/netdevice.h> #include <net/if_inet6.h> -extern struct inet6_ifaddr *inet6_addr_lst[16]; -extern struct ipv6_mc_list *inet6_mcast_lst[16]; -extern struct inet6_dev *inet6_dev_lst; +#define IN6_ADDR_HSIZE 16 + +extern struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE]; +extern struct ifmcaddr6 *inet6_mcast_lst[IN6_ADDR_HSIZE]; +extern struct inet6_dev *inet6_dev_lst[IN6_ADDR_HSIZE]; extern void addrconf_init(void); extern void addrconf_cleanup(void); @@ -51,10 +53,9 @@ extern int addrconf_notify(struct notifier_block *this, extern int addrconf_add_ifaddr(void *arg); extern int addrconf_set_dstaddr(void *arg); -extern int addrconf_get_ifindex(void *arg); extern struct inet6_ifaddr * ipv6_chk_addr(struct in6_addr *addr); -extern struct inet6_ifaddr * ipv6_get_saddr(struct rt6_info *rt, +extern struct inet6_ifaddr * ipv6_get_saddr(struct dst_entry *dst, struct in6_addr *daddr); extern struct inet6_ifaddr * ipv6_get_lladdr(struct device *dev); @@ -80,7 +81,6 @@ extern int ipv6_chk_mcast_addr(struct device *dev, extern void addrconf_prefix_rcv(struct device *dev, u8 *opt, int len); -extern struct inet6_dev * ipv6_dev_by_index(int index); extern struct inet6_dev * ipv6_get_idev(struct device *dev); extern void addrconf_forwarding_on(void); @@ -105,6 +105,11 @@ static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr) return ((tmp ^ (tmp >> 4)) & 0x0f); } +static __inline__ int ipv6_devindex_hash(int ifindex) +{ + return ifindex & (IN6_ADDR_HSIZE - 1); +} + /* * compute link-local solicited-node multicast address */ diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 86b0e1ea1..06970ac67 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -7,8 +7,29 @@ extern void unix_notinflight(struct file *fp); typedef struct sock unix_socket; extern void unix_gc(void); -extern unix_socket *unix_socket_list; +#define UNIX_HASH_SIZE 16 -#define UNIX_MAX_FD 8 +extern unix_socket *unix_socket_table[UNIX_HASH_SIZE+1]; + +#define forall_unix_sockets(i, s) for (i=0; i<=UNIX_HASH_SIZE; i++) \ + for (s=unix_socket_table[i]; s; s=s->next) + +struct unix_address +{ + atomic_t refcnt; + int len; + unsigned hash; + struct sockaddr_un name[0]; +}; + +struct unix_skb_parms +{ + struct ucred creds; /* Skb credentials */ + struct scm_fp_list *fp; /* Passed files */ + unsigned attr; /* Special attributes */ +}; + +#define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) +#define UNIXCREDS(skb) (&UNIXCB((skb)).creds) #endif diff --git a/include/net/arp.h b/include/net/arp.h index db7a29c36..dbd0c1281 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -2,16 +2,47 @@ #ifndef _ARP_H #define _ARP_H +#include <linux/if_arp.h> +#include <net/neighbour.h> +/* + * This structure defines the ARP mapping cache. + */ + +struct arp_table +{ + union { + struct neighbour neigh; + struct arp_table *next; + } u; + + u32 ip; + + unsigned long last_updated; /* For expiry */ + unsigned int flags; /* Control status */ + + u32 mask; /* netmask - used for generalised proxy arps (tridge) */ + int hatype; + + /* + * The following entries are only used for unresolved hw addresses. + */ + struct timer_list timer; /* expire timer */ + int retries; /* remaining retries */ +}; + extern void arp_init(void); extern int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); -extern int arp_query(unsigned char *haddr, u32 paddr, struct device *dev); -extern int arp_find(unsigned char *haddr, u32 paddr, - struct device *dev, u32 saddr, struct sk_buff *skb); +extern int arp_find(unsigned char *haddr, struct sk_buff *skb); +extern int arp_find_1(unsigned char *haddr, struct dst_entry* dst, + struct neighbour *neigh); extern int arp_ioctl(unsigned int cmd, void *arg); extern void arp_send(int type, int ptype, u32 dest_ip, struct device *dev, u32 src_ip, unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th); +extern int arp_req_set(struct arpreq *r, struct device *dev); +extern int arp_req_delete(struct arpreq *r, struct device *dev); extern int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short type, __u32 daddr); extern int arp_update_cache(struct hh_cache * hh); +extern struct neighbour *arp_find_neighbour(struct dst_entry *dst, int); #endif /* _ARP_H */ diff --git a/include/net/ax25.h b/include/net/ax25.h index 43cedaafb..71d7fb0b2 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -6,47 +6,46 @@ #ifndef _AX25_H #define _AX25_H +#include <linux/config.h> #include <linux/ax25.h> -#define PR_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */ +#define AX25_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */ -#define AX25_T1CLAMPLO (1 * PR_SLOWHZ) /* If defined, clamp at 1 second **/ -#define AX25_T1CLAMPHI (30 * PR_SLOWHZ) /* If defined, clamp at 30 seconds **/ +#define AX25_T1CLAMPLO (1 * AX25_SLOWHZ) /* If defined, clamp at 1 second **/ +#define AX25_T1CLAMPHI (30 * AX25_SLOWHZ) /* If defined, clamp at 30 seconds **/ -#define AX25_BROKEN_NETMAC +#define AX25_BPQ_HEADER_LEN 16 +#define AX25_KISS_HEADER_LEN 1 -#define AX25_BPQ_HEADER_LEN 16 -#define AX25_KISS_HEADER_LEN 1 +#define AX25_HEADER_LEN 17 +#define AX25_ADDR_LEN 7 +#define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN) +#define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN) -#define AX25_HEADER_LEN 17 -#define AX25_ADDR_LEN 7 -#define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN) -#define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN) - -#define AX25_P_ROSE 0x01 -#define AX25_P_IP 0xCC -#define AX25_P_ARP 0xCD -#define AX25_P_TEXT 0xF0 -#define AX25_P_NETROM 0xCF -#define AX25_P_SEGMENT 0x08 - -#define SEG_REM 0x7F -#define SEG_FIRST 0x80 +/* AX.25 Protocol IDs */ +#define AX25_P_ROSE 0x01 +#define AX25_P_IP 0xCC +#define AX25_P_ARP 0xCD +#define AX25_P_TEXT 0xF0 +#define AX25_P_NETROM 0xCF +#define AX25_P_SEGMENT 0x08 -#define LAPB_UI 0x03 -#define LAPB_C 0x80 -#define LAPB_E 0x01 +/* AX.25 Segment control values */ +#define AX25_SEG_REM 0x7F +#define AX25_SEG_FIRST 0x80 -#define SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */ -#define ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */ -#define DAMA_FLAG 0x20 /* Well, it is *NOT* unused! (dl1bke 951121 */ +#define AX25_CBIT 0x80 /* Command/Response bit */ +#define AX25_EBIT 0x01 /* HDLC Address Extension bit */ +#define AX25_HBIT 0x80 /* Has been repeated bit */ -#define AX25_REPEATED 0x80 +#define AX25_SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */ +#define AX25_ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */ +#define AX25_DAMA_FLAG 0x20 /* Well, it is *NOT* unused! (dl1bke 951121 */ -#define ACK_PENDING_CONDITION 0x01 -#define REJECT_CONDITION 0x02 -#define PEER_RX_BUSY_CONDITION 0x04 -#define OWN_RX_BUSY_CONDITION 0x08 +#define AX25_COND_ACK_PENDING 0x01 +#define AX25_COND_REJECT 0x02 +#define AX25_COND_PEER_RX_BUSY 0x04 +#define AX25_COND_OWN_RX_BUSY 0x08 #ifndef _LINUX_NETDEVICE_H #include <linux/netdevice.h> @@ -76,109 +75,144 @@ /* Upper sub-layer (LAPB) definitions */ /* Control field templates */ -#define I 0x00 /* Information frames */ -#define S 0x01 /* Supervisory frames */ -#define RR 0x01 /* Receiver ready */ -#define RNR 0x05 /* Receiver not ready */ -#define REJ 0x09 /* Reject */ -#define U 0x03 /* Unnumbered frames */ -#define SABM 0x2f /* Set Asynchronous Balanced Mode */ -#define SABME 0x6f /* Set Asynchronous Balanced Mode Extended */ -#define DISC 0x43 /* Disconnect */ -#define DM 0x0f /* Disconnected mode */ -#define UA 0x63 /* Unnumbered acknowledge */ -#define FRMR 0x87 /* Frame reject */ -#define UI 0x03 /* Unnumbered information */ -#define PF 0x10 /* Poll/final bit for standard AX.25 */ -#define EPF 0x01 /* Poll/final bit for extended AX.25 */ - -#define ILLEGAL 0x100 /* Impossible to be a real frame type */ - -#define POLLOFF 0 -#define POLLON 1 +#define AX25_I 0x00 /* Information frames */ +#define AX25_S 0x01 /* Supervisory frames */ +#define AX25_RR 0x01 /* Receiver ready */ +#define AX25_RNR 0x05 /* Receiver not ready */ +#define AX25_REJ 0x09 /* Reject */ +#define AX25_U 0x03 /* Unnumbered frames */ +#define AX25_SABM 0x2f /* Set Asynchronous Balanced Mode */ +#define AX25_SABME 0x6f /* Set Asynchronous Balanced Mode Extended */ +#define AX25_DISC 0x43 /* Disconnect */ +#define AX25_DM 0x0f /* Disconnected mode */ +#define AX25_UA 0x63 /* Unnumbered acknowledge */ +#define AX25_FRMR 0x87 /* Frame reject */ +#define AX25_UI 0x03 /* Unnumbered information */ + +#define AX25_PF 0x10 /* Poll/final bit for standard AX.25 */ +#define AX25_EPF 0x01 /* Poll/final bit for extended AX.25 */ + +#define AX25_ILLEGAL 0x100 /* Impossible to be a real frame type */ + +#define AX25_POLLOFF 0 +#define AX25_POLLON 1 /* AX25 L2 C-bit */ - -#define C_COMMAND 1 /* C_ otherwise it clashes with the de600 defines (sigh)) */ -#define C_RESPONSE 2 +#define AX25_COMMAND 1 +#define AX25_RESPONSE 2 /* Define Link State constants. */ -#define AX25_STATE_0 0 -#define AX25_STATE_1 1 -#define AX25_STATE_2 2 -#define AX25_STATE_3 3 -#define AX25_STATE_4 4 - -#define AX25_MAX_DEVICES 20 /* Max No of AX.25 devices */ - -#define MODULUS 8 /* Standard AX.25 modulus */ -#define EMODULUS 128 /* Extended AX.25 modulus */ - -#define AX25_DIGI_INBAND 0x01 /* Allow digipeating within port **/ -#define AX25_DIGI_XBAND 0x02 /* Allow digipeating across ports **/ - -#define AX25_VALUES_IPDEFMODE 0 /* 0=DG 1=VC */ -#define AX25_VALUES_AXDEFMODE 1 /* 0=Normal 1=Extended Seq Nos */ -#define AX25_VALUES_TEXT 2 /* Allow PID=Text - 0=No 1=Yes */ -#define AX25_VALUES_BACKOFF 3 /* 0=Linear 1=Exponential */ -#define AX25_VALUES_CONMODE 4 /* Allow connected modes - 0=No 1=Yes */ -#define AX25_VALUES_WINDOW 5 /* Default window size for standard AX.25 */ -#define AX25_VALUES_EWINDOW 6 /* Default window size for extended AX.25 */ -#define AX25_VALUES_T1 7 /* Default T1 timeout value */ -#define AX25_VALUES_T2 8 /* Default T2 timeout value */ -#define AX25_VALUES_T3 9 /* Default T3 timeout value */ -#define AX25_VALUES_IDLE 10 /* mode vc idle timer */ -#define AX25_VALUES_N2 11 /* Default N2 value */ -#define AX25_VALUES_PACLEN 12 /* AX.25 MTU */ -#define AX25_VALUES_MAXQUEUE 13 /* Maximum number of buffers enqueued */ -#define AX25_VALUES_DIGI 14 /* Digipeat mode */ -#define AX25_MAX_VALUES 15 +enum { + AX25_STATE_0, + AX25_STATE_1, + AX25_STATE_2, + AX25_STATE_3, + AX25_STATE_4 +}; + +#define AX25_MODULUS 8 /* Standard AX.25 modulus */ +#define AX25_EMODULUS 128 /* Extended AX.25 modulus */ + +enum { + AX25_PROTO_STD_SIMPLEX, + AX25_PROTO_STD_DUPLEX, + AX25_PROTO_DAMA_SLAVE, + AX25_PROTO_DAMA_MASTER +}; + +enum { + AX25_VALUES_IPDEFMODE, /* 0=DG 1=VC */ + AX25_VALUES_AXDEFMODE, /* 0=Normal 1=Extended Seq Nos */ + AX25_VALUES_BACKOFF, /* 0=None 1=Linear 2=Exponential */ + AX25_VALUES_CONMODE, /* Allow connected modes - 0=No 1=no "PID text" 2=all PIDs */ + AX25_VALUES_WINDOW, /* Default window size for standard AX.25 */ + AX25_VALUES_EWINDOW, /* Default window size for extended AX.25 */ + AX25_VALUES_T1, /* Default T1 timeout value */ + AX25_VALUES_T2, /* Default T2 timeout value */ + AX25_VALUES_T3, /* Default T3 timeout value */ + AX25_VALUES_IDLE, /* Connected mode idle timer */ + AX25_VALUES_N2, /* Default N2 value */ + AX25_VALUES_PACLEN, /* AX.25 MTU */ + AX25_VALUES_PROTOCOL, /* Std AX.25, DAMA Slave, DAMA Master */ + AX25_VALUES_DS_TIMEOUT, /* DAMA Slave timeout */ + AX25_MAX_VALUES /* THIS MUST REMAIN THE LAST ENTRY OF THIS LIST */ +}; #define AX25_DEF_IPDEFMODE 0 /* Datagram */ #define AX25_DEF_AXDEFMODE 0 /* Normal */ -#define AX25_DEF_TEXT 1 /* PID=Text allowed */ -#define AX25_DEF_BACKOFF 1 /* Exponential backoff */ -#define AX25_DEF_CONMODE 1 /* Connected mode allowed */ +#define AX25_DEF_BACKOFF 1 /* Linear backoff */ +#define AX25_DEF_CONMODE 2 /* Connected mode allowed */ #define AX25_DEF_WINDOW 2 /* Window=2 */ #define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */ -#define AX25_DEF_T1 (10 * PR_SLOWHZ) /* T1=10s */ -#define AX25_DEF_T2 (3 * PR_SLOWHZ) /* T2=3s */ -#define AX25_DEF_T3 (300 * PR_SLOWHZ) /* T3=300s */ +#define AX25_DEF_T1 (10 * AX25_SLOWHZ) /* T1=10s */ +#define AX25_DEF_T2 (3 * AX25_SLOWHZ) /* T2=3s */ +#define AX25_DEF_T3 (300 * AX25_SLOWHZ) /* T3=300s */ #define AX25_DEF_N2 10 /* N2=10 */ -#define AX25_DEF_IDLE (20 * 60 * PR_SLOWHZ) /* Idle=20 mins */ +#define AX25_DEF_IDLE (20 * 60 * AX25_SLOWHZ) /* Idle=20 mins */ #define AX25_DEF_PACLEN 256 /* Paclen=256 */ -#define AX25_DEF_MAXQUEUE 2 /* 1 * ax25->window */ -#define AX25_DEF_DIGI 0x03 /* All digis alowed */ +#define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */ +#define AX25_DEF_DS_TIMEOUT (3 * 60 * AX25_SLOWHZ) /* DAMA timeout 3 minutes */ typedef struct ax25_uid_assoc { - struct ax25_uid_assoc *next; - uid_t uid; - ax25_address call; + struct ax25_uid_assoc *next; + uid_t uid; + ax25_address call; } ax25_uid_assoc; typedef struct { - ax25_address calls[AX25_MAX_DIGIS]; - unsigned char repeated[AX25_MAX_DIGIS]; - unsigned char ndigi; - char lastrepeat; + ax25_address calls[AX25_MAX_DIGIS]; + unsigned char repeated[AX25_MAX_DIGIS]; + unsigned char ndigi; + char lastrepeat; } ax25_digi; +typedef struct ax25_route { + struct ax25_route *next; + ax25_address callsign; + struct device *dev; + ax25_digi *digipeat; + char ip_mode; +} ax25_route; + +typedef struct { + char slave; /* slave_mode? */ + struct timer_list slave_timer; /* timeout timer */ + unsigned short slave_timeout; /* when? */ +} ax25_dama_info; + +#ifndef _LINUX_SYSCTL_H +#include <linux/sysctl.h> +#endif + +typedef struct ax25_dev { + struct ax25_dev *next; + struct device *dev; + struct device *forward; + struct ctl_table systable[AX25_MAX_VALUES+1]; + int values[AX25_MAX_VALUES]; +#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER) + ax25_dama_info dama; +#endif +} ax25_dev; + typedef struct ax25_cb { struct ax25_cb *next; ax25_address source_addr, dest_addr; - struct device *device; - unsigned char dama_slave; /* dl1bke 951121 */ + ax25_digi *digipeat; + ax25_dev *ax25_dev; + unsigned char iamdigi; unsigned char state, modulus, hdrincl; unsigned short vs, vr, va; unsigned char condition, backoff; unsigned char n2, n2count; +#ifdef CONFIG_AX25_DAMA_SLAVE + unsigned char dama_slave; +#endif unsigned short t1, t2, t3, idle, rtt; unsigned short t1timer, t2timer, t3timer, idletimer; unsigned short paclen; - unsigned short maxqueue; unsigned short fragno, fraglen; - ax25_digi *digipeat; struct sk_buff_head write_queue; struct sk_buff_head reseq_queue; struct sk_buff_head ack_queue; @@ -188,65 +222,114 @@ typedef struct ax25_cb { struct sock *sk; /* Backlink to socket */ } ax25_cb; -struct ax25_dev { - char name[20]; - struct device *dev; - int values[AX25_MAX_VALUES]; -}; - /* af_ax25.c */ +extern ax25_cb *volatile ax25_list; +extern void ax25_free_cb(ax25_cb *); +extern void ax25_insert_socket(ax25_cb *); +struct sock *ax25_find_listener(ax25_address *, int, struct device *, int); +struct sock *ax25_find_socket(ax25_address *, ax25_address *, int); +extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct device *); +extern struct sock *ax25_addr_match(ax25_address *); +extern void ax25_send_to_raw(struct sock *, struct sk_buff *, int); +extern void ax25_destroy_socket(ax25_cb *); +extern ax25_cb *ax25_create_cb(void); +extern void ax25_fillin_cb(ax25_cb *, ax25_dev *); +extern int ax25_create(struct socket *, int); +extern struct sock *ax25_make_new(struct sock *, struct device *); + +/* ax25_addr.c */ extern ax25_address null_ax25_address; extern char *ax2asc(ax25_address *); extern ax25_address *asc2ax(char *); extern int ax25cmp(ax25_address *, ax25_address *); -extern int ax25_send_frame(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *, struct device *); -extern int ax25_link_up(ax25_address *, ax25_address *, struct device *); -extern void ax25_destroy_socket(ax25_cb *); -extern struct device *ax25rtr_get_dev(ax25_address *); -extern int ax25_encapsulate(struct sk_buff *, struct device *, unsigned short, - void *, void *, unsigned int); -extern int ax25_rebuild_header(unsigned char *, struct device *, unsigned long, struct sk_buff *); -extern ax25_uid_assoc *ax25_uid_list; -extern int ax25_uid_policy; -extern ax25_address *ax25_findbyuid(uid_t); -extern void ax25_queue_xmit(struct sk_buff *, struct device *, int); -extern int ax25_dev_is_dama_slave(struct device *); /* dl1bke 951121 */ +extern int ax25digicmp(ax25_digi *, ax25_digi *); +extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *); +extern int ax25_addr_build(unsigned char *, ax25_address *, ax25_address *, ax25_digi *, int, int); +extern int ax25_addr_size(ax25_digi *); +extern void ax25_digi_invert(ax25_digi *, ax25_digi *); + +/* ax25_dev.c */ +extern ax25_dev *ax25_dev_list; +extern ax25_dev *ax25_dev_ax25dev(struct device *); +extern ax25_dev *ax25_addr_ax25dev(ax25_address *); +extern void ax25_dev_device_up(struct device *); +extern void ax25_dev_device_down(struct device *); +extern int ax25_fwd_ioctl(unsigned int, struct ax25_fwd_struct *); +extern struct device *ax25_fwd_dev(struct device *); +extern void ax25_dev_free(void); + +/* ax25_ds_in.c */ +extern int ax25_ds_frame_in(ax25_cb *, struct sk_buff *, int); + +/* ax25_ds_subr.c */ +extern void ax25_ds_nr_error_recovery(ax25_cb *); +extern void ax25_ds_enquiry_response(ax25_cb *); +extern void ax25_ds_establish_data_link(ax25_cb *); +extern void ax25_dev_dama_on(ax25_dev *); +extern void ax25_dev_dama_off(ax25_dev *); +extern void ax25_dama_on(ax25_cb *); +extern void ax25_dama_off(ax25_cb *); + +/* ax25_ds_timer.c */ +extern void ax25_ds_set_timer(ax25_dev *); +extern void ax25_ds_del_timer(ax25_dev *); +extern void ax25_ds_timer(ax25_cb *); +extern void ax25_ds_t1_timeout(ax25_cb *); #include <net/ax25call.h> +/* ax25_iface.c */ +extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *)); +extern void ax25_protocol_release(unsigned int); +extern int ax25_linkfail_register(void (*)(ax25_address *, struct device *)); +extern void ax25_linkfail_release(void (*)(ax25_address *, struct device *)); +extern int ax25_listen_register(ax25_address *, struct device *); +extern void ax25_listen_release(ax25_address *, struct device *); +extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *); +extern int ax25_listen_mine(ax25_address *, struct device *); +extern void ax25_link_failed(ax25_address *, struct device *); +extern int ax25_link_up(ax25_address *, ax25_address *, ax25_digi *, struct device *); +extern int ax25_protocol_is_registered(unsigned int); + /* ax25_in.c */ -extern int ax25_process_rx_frame(ax25_cb *, struct sk_buff *, int, int); +extern int ax25_rx_iframe(ax25_cb *, struct sk_buff *); +extern int ax25_kiss_rcv(struct sk_buff *, struct device *, struct packet_type *); + +/* ax25_ip.c */ +extern int ax25_encapsulate(struct sk_buff *, struct device *, unsigned short, void *, void *, unsigned int); +extern int ax25_rebuild_header(struct sk_buff *); /* ax25_out.c */ -extern void ax25_output(ax25_cb *, struct sk_buff *); +extern int ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct device *); +extern void ax25_output(ax25_cb *, int, struct sk_buff *); extern void ax25_kick(ax25_cb *); extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int); -extern void ax25_nr_error_recovery(ax25_cb *); -extern void ax25_establish_data_link(ax25_cb *); -extern void ax25_transmit_enquiry(ax25_cb *); -extern void ax25_enquiry_response(ax25_cb *); -extern void ax25_timeout_response(ax25_cb *); +extern void ax25_queue_xmit(struct sk_buff *); extern void ax25_check_iframes_acked(ax25_cb *, unsigned short); -extern void ax25_check_need_response(ax25_cb *, int, int); -extern void dama_enquiry_response(ax25_cb *); /* dl1bke 960114 */ -extern void dama_check_need_response(ax25_cb *, int, int); /* dl1bke 960114 */ -extern void dama_establish_data_link(ax25_cb *); /* ax25_route.c */ -extern struct ax25_dev ax25_device[]; +extern void ax25_rt_device_down(struct device *); +extern int ax25_rt_ioctl(unsigned int, void *); extern int ax25_rt_get_info(char *, char **, off_t, int, int); -extern int ax25_cs_get_info(char *, char **, off_t, int, int); extern int ax25_rt_autobind(ax25_cb *, ax25_address *); extern void ax25_rt_build_path(ax25_cb *, ax25_address *, struct device *); extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *); -extern void ax25_rt_device_down(struct device *); -extern int ax25_rt_ioctl(unsigned int, void *); extern char ax25_ip_mode_get(ax25_address *, struct device *); -extern int ax25_dev_get_value(struct device *, int); -extern void ax25_dev_device_up(struct device *); -extern void ax25_dev_device_down(struct device *); extern void ax25_rt_free(void); +/* ax25_std_in.c */ +extern int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int); + +/* ax25_std_subr.c */ +extern void ax25_std_nr_error_recovery(ax25_cb *); +extern void ax25_std_establish_data_link(ax25_cb *); +extern void ax25_std_transmit_enquiry(ax25_cb *); +extern void ax25_std_enquiry_response(ax25_cb *); +extern void ax25_std_timeout_response(ax25_cb *); + +/* ax25_std_timer.c */ +extern void ax25_std_timer(ax25_cb *); + /* ax25_subr.c */ extern void ax25_clear_queues(ax25_cb *); extern void ax25_frames_acked(ax25_cb *, unsigned short); @@ -254,40 +337,22 @@ extern void ax25_requeue_frames(ax25_cb *); extern int ax25_validate_nr(ax25_cb *, unsigned short); extern int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *); extern void ax25_send_control(ax25_cb *, int, int, int); +extern void ax25_return_dm(struct device *, ax25_address *, ax25_address *, ax25_digi *); extern unsigned short ax25_calculate_t1(ax25_cb *); extern void ax25_calculate_rtt(ax25_cb *); -extern unsigned char *ax25_parse_addr(unsigned char *, int, ax25_address *, - ax25_address *, ax25_digi *, int *, int *); /* dl1bke 951121 */ -extern int build_ax25_addr(unsigned char *, ax25_address *, ax25_address *, - ax25_digi *, int, int); -extern int size_ax25_addr(ax25_digi *); -extern void ax25_digi_invert(ax25_digi *, ax25_digi *); -extern void ax25_return_dm(struct device *, ax25_address *, ax25_address *, ax25_digi *); -extern int ax25_queue_length(ax25_cb *, struct sk_buff *); /* dl1bke 960327 */ -extern void ax25_dama_on(ax25_cb *); /* dl1bke 951121 */ -extern void ax25_dama_off(ax25_cb *); /* dl1bke 951121 */ /* ax25_timer.c */ extern void ax25_set_timer(ax25_cb *); -extern void ax25_t1_timeout(ax25_cb *); -extern void ax25_link_failed(ax25_address *, struct device *); -extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *); -extern int ax25_listen_mine(ax25_address *, struct device *); + +/* ax25_uid.c */ +extern int ax25_uid_policy; +extern ax25_address *ax25_findbyuid(uid_t); +extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); +extern int ax25_uid_get_info(char *, char **, off_t, int, int); +extern void ax25_uid_free(void); /* sysctl_net_ax25.c */ extern void ax25_register_sysctl(void); extern void ax25_unregister_sysctl(void); -/* ... */ - -extern ax25_cb *volatile ax25_list; - -/* support routines for modules that use AX.25, in ax25_timer.c */ -extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *)); -extern void ax25_protocol_release(unsigned int); -extern int ax25_linkfail_register(void (*)(ax25_address *, struct device *)); -extern void ax25_linkfail_release(void (*)(ax25_address *, struct device *)); -extern int ax25_listen_register(ax25_address *, struct device *); -extern void ax25_listen_release(ax25_address *, struct device *); - #endif diff --git a/include/net/br.h b/include/net/br.h index a1d3fa309..3b4ccf094 100644 --- a/include/net/br.h +++ b/include/net/br.h @@ -208,84 +208,19 @@ struct br_cf { #define BRCMD_DISABLE_PROT_STATS 14 #define BRCMD_ZERO_PROT_STATS 15 -/* prototypes of all bridging functions... */ - -void transmit_config(int port_no); -int root_bridge(void); -int supersedes_port_info(int port_no, Config_bpdu *config); -void record_config_information(int port_no, Config_bpdu *config); -void record_config_timeout_values(Config_bpdu *config); -void config_bpdu_generation(void); -int designated_port(int port_no); -void reply(int port_no); -void transmit_tcn(void); -void configuration_update(void); -void root_selection(void); -void designated_port_selection(void); -void become_designated_port(int port_no); -void port_state_selection(void); -void make_forwarding(int port_no); -void topology_change_detection(void); -void topology_change_acknowledged(void); -void acknowledge_topology_change(int port_no); -void make_blocking(int port_no); -void set_port_state(int port_no, int state); -void received_config_bpdu(int port_no, Config_bpdu *config); -void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn); -void hello_timer_expiry(void); -void message_age_timer_expiry(int port_no); -void forward_delay_timer_expiry(int port_no); -int designated_for_some_port(void); -void tcn_timer_expiry(void); -void topology_change_timer_expiry(void); -void hold_timer_expiry(int port_no); -void br_init(void); -void br_init_port(int port_no); -void enable_port(int port_no); -void disable_port(int port_no); -void set_bridge_priority(bridge_id_t *new_bridge_id); -void set_port_priority(int port_no, unsigned short new_port_id); -void set_path_cost(int port_no, unsigned short path_cost); -void start_hello_timer(void); -void stop_hello_timer(void); -int hello_timer_expired(void); -void start_tcn_timer(void); -void stop_tcn_timer(void); -int tcn_timer_expired(void); -void start_topology_change_timer(void); -void stop_topology_change_timer(void); -int topology_change_timer_expired(void); -void start_message_age_timer(int port_no, unsigned short message_age); -void stop_message_age_timer(int port_no); -int message_age_timer_expired(int port_no); -void start_forward_delay_timer(int port_no); -void stop_forward_delay_timer(int port_no); -int forward_delay_timer_expired(int port_no); -void start_hold_timer(int port_no); -void stop_hold_timer(int port_no); -int hold_timer_expired(int port_no); - -struct fdb *br_avl_find_addr(unsigned char addr[6]); -int br_avl_insert (struct fdb * new_node); -int br_avl_remove (struct fdb * node_to_delete); - -int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu); -int send_config_bpdu(int port_no, Config_bpdu *config_bpdu); -int find_port(struct device *dev); -int br_flood(struct sk_buff *skb, int port); -int br_drop(struct sk_buff *skb); -int br_learn(struct sk_buff *skb, int port); /* 3.8 */ +/* prototypes of exported bridging functions... */ +void br_init(void); int br_receive_frame(struct sk_buff *skb); /* 3.5 */ int br_tx_frame(struct sk_buff *skb); int br_ioctl(unsigned int cmd, void *arg); - int br_protocol_ok(unsigned short protocol); -void free_fdb(struct fdb *); -struct fdb *get_fdb(void); +struct fdb *br_avl_find_addr(unsigned char addr[6]); +int br_avl_insert (struct fdb * new_node); /* externs */ extern struct br_stat br_stats; + diff --git a/include/net/dst.h b/include/net/dst.h new file mode 100644 index 000000000..9d2a69100 --- /dev/null +++ b/include/net/dst.h @@ -0,0 +1,126 @@ +/* + * net/dst.h Protocol independent destination cache definitions. + * + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> + * + */ + +#ifndef _NET_DST_H +#define _NET_DST_H + +#include <net/neighbour.h> + +/* + * 0 - no debugging messages + * 1 - rare events and bugs (default) + * 2 - trace mode. + */ +#ifdef NO_ANK_FIX +#define RT_CACHE_DEBUG 0 +#else +#define RT_CACHE_DEBUG 1 +#endif + +#define DST_GC_MIN (1*HZ) +#define DST_GC_INC (5*HZ) +#define DST_GC_MAX (120*HZ) + +struct sk_buff; + +struct dst_entry +{ + struct dst_entry *next; + atomic_t refcnt; /* tree/hash references */ + atomic_t use; /* client references */ + struct device *dev; + char obsolete; + char priority; + char __pad1, __pad2; + unsigned long lastuse; + unsigned window; + unsigned pmtu; + unsigned rtt; + int error; + + struct neighbour *neighbour; + struct hh_cache *hh; + + int (*input)(struct sk_buff*); + int (*output)(struct sk_buff*); + + struct dst_ops *ops; + + char info[0]; +}; + + +struct dst_ops +{ + unsigned short family; + struct dst_entry * (*check)(struct dst_entry *, u32 cookie); + struct dst_entry * (*reroute)(struct dst_entry *, + struct sk_buff *); + void (*destroy)(struct dst_entry *); +}; + +extern struct dst_entry * dst_garbage_list; +extern atomic_t dst_total; + +static __inline__ +struct dst_entry * dst_clone(struct dst_entry * dst) +{ + if (dst) + atomic_inc(&dst->use); + return dst; +} + +static __inline__ +void dst_release(struct dst_entry * dst) +{ + if (dst) + atomic_dec(&dst->use); +} + +static __inline__ +struct dst_entry * dst_check(struct dst_entry ** dst_p, u32 cookie) +{ + struct dst_entry * dst = *dst_p; + if (dst && dst->obsolete) + dst = dst->ops->check(dst, cookie); + return (*dst_p = dst); +} + +static __inline__ +struct dst_entry * dst_reroute(struct dst_entry ** dst_p, struct sk_buff *skb) +{ + struct dst_entry * dst = *dst_p; + if (dst && dst->obsolete) + dst = dst->ops->reroute(dst, skb); + return (*dst_p = dst); +} + +static __inline__ +void dst_destroy(struct dst_entry * dst) +{ + if (dst->neighbour) + neigh_release(dst->neighbour); + if (dst->ops->destroy) + dst->ops->destroy(dst); + kfree(dst); + atomic_dec(&dst_total); +} + +extern void * dst_alloc(int size, struct dst_ops * ops); +extern void __dst_free(struct dst_entry * dst); + +static __inline__ +void dst_free(struct dst_entry * dst) +{ + if (!atomic_read(&dst->use)) { + dst_destroy(dst); + return; + } + __dst_free(dst); +} + +#endif /* _NET_DST_H */ diff --git a/include/net/flow.h b/include/net/flow.h new file mode 100644 index 000000000..dff77fc6a --- /dev/null +++ b/include/net/flow.h @@ -0,0 +1,95 @@ +/* + * + * Flow based forwarding rules (usage: firewalling, etc) + * + */ + +#ifndef _NET_FLOW_H +#define _NET_FLOW_H + +struct flowi { + int proto; /* {TCP, UDP, ICMP} */ + + union { + struct { + __u32 daddr; + __u32 saddr; + } ip4_u; + + struct { + struct in6_addr * daddr; + struct in6_addr * saddr; + } ip6_u; + } nl_u; + + struct device *dev; + + union { + struct { + __u16 sport; + __u16 dport; + } ports; + + struct { + __u8 type; + __u8 code; + } icmpt; + + unsigned long data; + } uli_u; +}; + +#define FLOWR_NODECISION 0 /* rule not appliable to flow */ +#define FLOWR_SELECT 1 /* flow must follow this rule */ +#define FLOWR_CLEAR 2 /* priority level clears flow */ +#define FLOWR_ERROR 3 + +struct fl_acc_args { + int type; + + +#define FL_ARG_FORWARD 1 +#define FL_ARG_ORIGIN 2 + + union { + struct sk_buff *skb; + struct { + struct sock *sk; + struct flowi *flow; + } fl_o; + } fl_u; +}; + + +struct pkt_filter { + atomic_t refcnt; + unsigned int offset; + __u32 value; + __u32 mask; + struct pkt_filter *next; +}; + +#define FLR_INPUT 1 +#define FLR_OUTPUT 2 + +struct flow_filter { + int type; + union { + struct pkt_filter *filter; + struct sock *sk; + } u; +}; + +struct flow_rule { + struct flow_rule_ops *ops; + unsigned char private[0]; +}; + +struct flow_rule_ops { + int (*accept)(struct rt6_info *rt, + struct rt6_info *rule, + struct fl_acc_args *args, + struct rt6_info **nrt); +}; + +#endif diff --git a/include/net/icmp.h b/include/net/icmp.h index fa770d238..a936803eb 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h @@ -28,14 +28,10 @@ extern struct icmp_err icmp_err_convert[]; extern struct icmp_mib icmp_statistics; extern void icmp_send(struct sk_buff *skb_in, int type, int code, - unsigned long info, struct device *dev); -extern int icmp_rcv(struct sk_buff *skb1, struct device *dev, - struct options *opt, __u32 daddr, - unsigned short len, __u32 saddr, - int redo, struct inet_protocol *protocol); -extern int icmp_ioctl(struct sock *sk, int cmd, - unsigned long arg); -extern void icmp_init(struct proto_ops *ops); + unsigned long info); +extern int icmp_rcv(struct sk_buff *skb, unsigned short len); +extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern void icmp_init(struct net_proto_family *ops); /* CONFIG_IP_TRANSPARENT_PROXY */ extern int icmp_chkaddr(struct sk_buff *skb); diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 048243c33..281c2f099 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -59,14 +59,17 @@ struct ipv6_mc_socklist { struct ipv6_mc_socklist *next; }; -struct ipv6_mc_list { - struct in6_addr addr; +#define MAF_TIMER_RUNNING 0x01 +#define MAF_LAST_REPORTER 0x02 + +struct ifmcaddr6 { + struct in6_addr mca_addr; struct device *dev; - struct ipv6_mc_list *next; - struct ipv6_mc_list *if_next; - struct timer_list timer; - int tm_running; - atomic_t users; + struct ifmcaddr6 *next; + struct ifmcaddr6 *if_next; + struct timer_list mca_timer; + unsigned long mca_flags; + atomic_t mca_users; }; #define IFA_HOST IPV6_ADDR_LOOPBACK @@ -81,9 +84,8 @@ struct inet6_dev struct device *dev; struct inet6_ifaddr *addr_list; - struct ipv6_mc_list *mc_list; + struct ifmcaddr6 *mc_list; - __u32 if_index; __u32 if_flags; __u32 router:1, unused:31; diff --git a/include/net/inet_common.h b/include/net/inet_common.h index c72c75333..728b6662e 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h @@ -1,10 +1,8 @@ #ifndef _INET_COMMON_H #define _INET_COMMON_H -extern struct proto_ops inet_proto_ops; -extern struct sock * tcp_sock_array[SOCK_ARRAY_SIZE]; -extern struct sock * udp_sock_array[SOCK_ARRAY_SIZE]; - +extern struct proto_ops inet_stream_ops; +extern struct proto_ops inet_dgram_ops; /* * INET4 prototypes used by INET6 @@ -15,22 +13,22 @@ extern void inet_put_sock(unsigned short num, struct sock *sk); extern int inet_release(struct socket *sock, struct socket *peer); -extern int inet_connect(struct socket *sock, - struct sockaddr * uaddr, - int addr_len, int flags); +extern int inet_stream_connect(struct socket *sock, + struct sockaddr * uaddr, + int addr_len, int flags); +extern int inet_dgram_connect(struct socket *sock, + struct sockaddr * uaddr, + int addr_len, int flags); extern int inet_accept(struct socket *sock, struct socket *newsock, int flags); extern int inet_recvmsg(struct socket *sock, struct msghdr *ubuf, - int size, int noblock, - int flags, int *addr_len ); + int size, int flags, struct scm_cookie *scm); extern int inet_sendmsg(struct socket *sock, struct msghdr *msg, - int size, int noblock, - int flags); + int size, struct scm_cookie *scm); extern int inet_shutdown(struct socket *sock, int how); -extern int inet_select(struct socket *sock, int sel_type, - select_table *wait); +extern unsigned int inet_poll(struct socket *sock, poll_table *wait); extern int inet_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen); diff --git a/include/net/ip.h b/include/net/ip.h index f7bb04c53..c0e600a37 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -33,6 +33,26 @@ #include <net/sock.h> /* struct sock */ +struct inet_skb_parm +{ + struct ip_options opt; /* Compiled IP options */ + u16 redirport; /* Redirect port */ + unsigned char flags; + char vif; + +#define IPSKB_MASQUERADED 1 +#define IPSKB_TRANSLATED 2 +#define IPSKB_TUNNELED 4 +}; + +struct ipcm_cookie +{ + u32 addr; + struct ip_options *opt; +}; + +#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) + /* IP flags. */ #define IP_CE 0x8000 /* Flag: "Congestion" */ #define IP_DF 0x4000 /* Flag: "Don't Fragment" */ @@ -41,13 +61,9 @@ #define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ -#ifdef CONFIG_IP_MULTICAST extern void ip_mc_dropsocket(struct sock *); extern void ip_mc_dropdevice(struct device *dev); extern int ip_mc_procinfo(char *, char **, off_t, int, int); -#endif - -#include <net/ip_forward.h> /* Describe an IP fragment. */ struct ipfrag @@ -83,72 +99,119 @@ struct ipq * Functions provided by ip.c */ -extern void ip_print(const struct iphdr *ip); extern int ip_ioctl(struct sock *sk, int cmd, unsigned long arg); -extern void ip_route_check(__u32 daddr); -extern int ip_send(struct rtable *rt, struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr); -extern int ip_build_header(struct sk_buff *skb, - __u32 saddr, - __u32 daddr, - struct device **dev, int type, - struct options *opt, int len, - int tos,int ttl,struct rtable **rp); +extern int ip_build_pkt(struct sk_buff *skb, struct sock *sk, + u32 saddr, u32 daddr, + struct ip_options *opt); +extern int ip_build_header(struct sk_buff *skb, struct sock *sk); extern int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); -extern int ip_options_echo(struct options * dopt, struct options * sopt, - __u32 daddr, __u32 saddr, - struct sk_buff * skb); -extern int ip_options_compile(struct options * opt, struct sk_buff * skb); +extern int ip_local_deliver(struct sk_buff *skb); +extern int ip_mr_input(struct sk_buff *skb); +extern int ip_output(struct sk_buff *skb); +extern int ip_mc_output(struct sk_buff *skb); +#ifdef CONFIG_IP_ACCT +extern int ip_acct_output(struct sk_buff *skb); +#else +#define ip_acct_output dev_queue_xmit +#endif +extern void ip_fragment(struct sk_buff *skb, int, int (*out)(struct sk_buff*)); +extern struct sk_buff * ip_reply(struct sk_buff *skb, int payload); +extern int ip_do_nat(struct sk_buff *skb); extern void ip_send_check(struct iphdr *ip); extern int ip_id_count; -extern void ip_queue_xmit(struct sock *sk, - struct device *dev, struct sk_buff *skb, - int free); +extern void ip_queue_xmit(struct sk_buff *skb); extern void ip_init(void); extern int ip_build_xmit(struct sock *sk, int getfrag (const void *, - __u32, char *, unsigned int, unsigned int), const void *frag, unsigned short int length, - __u32 daddr, - __u32 saddr, - struct options * opt, - int flags, - int type, - int noblock); + struct ipcm_cookie *ipc, + struct rtable *rt, + int flags); + + +static __inline__ +void ip_send(struct sk_buff *skb) +{ + ip_ll_header(skb); + + if (skb->len > skb->dev->mtu + skb->dev->hard_header_len) + ip_fragment(skb, 0, ip_acct_output); + else + ip_acct_output(skb); +} + +static __inline__ +int ip_decrease_ttl(struct iphdr *iph) +{ + u16 check = iph->check; + check = ntohs(check) + 0x0100; + if ((check & 0xFF00) == 0) + check++; /* carry overflow */ + iph->check = htons(check); + return --iph->ttl; +} extern struct ip_mib ip_statistics; +struct ipv4_config +{ + int accept_redirects; + int secure_redirects; + int rfc1620_redirects; + int rfc1812_filter; + int addrmask_agent; + int log_martians; + int source_route; + int multicast_route; + int bootp_agent; + int bootp_relay; + int fib_model; + int no_pmtu_disc; +}; + +extern struct ipv4_config ipv4_config; + +#define IS_ROUTER (ip_statistics.IpForwarding == 1) + /* * Functions provided by ip_fragment.o */ -struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device *dev); -void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int is_frag); +struct sk_buff *ip_defrag(struct sk_buff *skb); /* * Functions provided by ip_forward.c */ -extern int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, __u32 target_addr); +extern int ip_forward(struct sk_buff *skb); +extern int ip_net_unreachable(struct sk_buff *skb); /* * Functions provided by ip_options.c */ -extern void ip_options_build(struct sk_buff *skb, struct options *opt, __u32 daddr, __u32 saddr, int is_frag); -extern int ip_options_echo(struct options *dopt, struct options *sopt, __u32 daddr, __u32 saddr, struct sk_buff *skb); +extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, u32 daddr, u32 saddr, int is_frag); +extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb); extern void ip_options_fragment(struct sk_buff *skb); -extern int ip_options_compile(struct options *opt, struct sk_buff *skb); +extern int ip_options_compile(struct ip_options *opt, struct sk_buff *skb); +extern int ip_options_get(struct ip_options **optp, unsigned char *data, int optlen, int user); +extern void ip_options_undo(struct ip_options * opt); +extern void ip_forward_options(struct sk_buff *skb); +extern int ip_options_rcv_srr(struct sk_buff *skb); /* * Functions provided by ip_sockglue.c */ -extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); -extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen); - +extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); +extern int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc, struct device **devp); +extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); +extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen); + +extern int ipv4_backlog_rcv(struct sock *sk, struct sk_buff *skb); #endif /* _IP_H */ diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h new file mode 100644 index 000000000..482c7c74a --- /dev/null +++ b/include/net/ip6_fib.h @@ -0,0 +1,153 @@ +/* + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _IP6_FIB_H +#define _IP6_FIB_H + +#ifdef __KERNEL__ + +#include <linux/ipv6_route.h> + +#include <net/dst.h> +#include <net/flow.h> + +struct rt6_info; + +struct fib6_node { + struct fib6_node *parent; + struct fib6_node *left; + struct fib6_node *right; + + struct fib6_node *subtree; + + struct rt6_info *leaf; + + __u16 fn_bit; /* bit key */ + __u16 fn_flags; + __u32 fn_sernum; +}; + + +/* + * routing information + * + */ + +struct rt6key { + struct in6_addr addr; + int plen; +}; + +struct rt6_info { + union { + struct dst_entry dst; + struct rt6_info *next; + } u; + +#define rt6i_dev u.dst.dev +#define rt6i_nexthop u.dst.neighbour +#define rt6i_use u.dst.use +#define rt6i_ref u.dst.refcnt + +#define rt6i_tstamp u.dst.lastuse + + struct fib6_node *rt6i_node; + + struct in6_addr rt6i_gateway; + + int rt6i_keylen; + + unsigned long rt6i_flags; + unsigned long rt6i_metric; + unsigned long rt6i_expires; + + union { + struct flow_rule *rt6iu_flowr; + struct flow_filter *rt6iu_filter; + } flow_u; + +#define rt6i_flowr flow_u.rt6iu_flowr +#define rt6i_filter flow_u.rt6iu_filter + + struct rt6key rt6i_dst; + struct rt6key rt6i_src; +}; + + +struct rt6_statistics { + __u32 fib_nodes; + __u32 fib_route_nodes; + __u32 fib_rt_alloc; /* permanet routes */ + __u32 fib_rt_entries; /* rt entries in table */ + __u32 fib_rt_cache; /* cache routes */ +}; + +#define RTN_TL_ROOT 0x0001 +#define RTN_ROOT 0x0002 /* tree root node */ +#define RTN_RTINFO 0x0004 /* node with valid routing info */ + +#define RTN_TAG 0x0100 + +/* + * priority levels (or metrics) + * + */ + +#define RTPRI_FIREWALL 8 /* Firewall control information */ +#define RTPRI_FLOW 16 /* Flow based forwarding rules */ +#define RTPRI_KERN_CTL 32 /* Kernel control routes */ + +#define RTPRI_USER_MIN 256 /* Mimimum user priority */ +#define RTPRI_USER_MAX 1024 /* Maximum user priority */ + +#define RTPRI_KERN_DFLT 4096 /* Kernel default routes */ + +#define MAX_FLOW_BACKTRACE 32 + + +typedef void (*f_pnode)(struct fib6_node *fn, void *); + +extern struct fib6_node ip6_routing_table; + +/* + * exported functions + */ + +extern struct fib6_node *fib6_lookup(struct fib6_node *root, + struct in6_addr *daddr, + struct in6_addr *saddr); + +#define RT6_FILTER_RTNODES 1 + +extern void fib6_walk_tree(struct fib6_node *root, + f_pnode func, void *arg, + int filter); + +extern int fib6_add(struct fib6_node *root, + struct rt6_info *rt); + +extern int fib6_del(struct rt6_info *rt); + +/* + * auxiliary functions + */ +extern __inline__ void rt6_release(struct rt6_info *rt) +{ + struct dst_entry *dst = (struct dst_entry *) rt; + if (atomic_dec_and_test(&dst->refcnt)) + dst_destroy(dst); +} + +extern void rt6_ins(struct rt6_info *rt); + +#endif +#endif diff --git a/include/net/ip6_fw.h b/include/net/ip6_fw.h new file mode 100644 index 000000000..7866273d3 --- /dev/null +++ b/include/net/ip6_fw.h @@ -0,0 +1,54 @@ +#ifndef __NET_IP6_FW_H +#define __NET_IP6_FW_H + +#define IP6_FW_LISTHEAD 0x1000 +#define IP6_FW_ACCEPT 0x0001 +#define IP6_FW_REJECT 0x0002 + +#define IP6_FW_DEBUG 2 + +#define IP6_FW_MSG_ADD 1 +#define IP6_FW_MSG_DEL 2 +#define IP6_FW_MSG_REPORT 3 + + +/* + * Fast "hack" user interface + */ +struct ip6_fw_msg { + struct in6_addr dst; + struct in6_addr src; + int dst_len; + int src_len; + int action; + int policy; + int proto; + union { + struct { + __u16 sport; + __u16 dport; + } transp; + + unsigned long data; + + int icmp_type; + } u; + + int msg_len; +}; + +#ifdef __KERNEL__ + +#include <net/flow.h> + +struct ip6_fw_rule { + struct flow_rule flowr; + struct ip6_fw_rule *next; + struct ip6_fw_rule *prev; + struct flowi info; + unsigned long policy; +}; + +#endif + +#endif diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h new file mode 100644 index 000000000..bdbe5c575 --- /dev/null +++ b/include/net/ip6_route.h @@ -0,0 +1,111 @@ +#ifndef _NET_IP6_ROUTE_H +#define _NET_IP6_ROUTE_H + +#define IP6_RT_PRIO_FW 16 +#define IP6_RT_PRIO_USER 1024 +#define IP6_RT_PRIO_ADDRCONF 256 +#define IP6_RT_PRIO_KERN 512 +#define IP6_RT_FLOW_MASK 0x00ff + +#ifdef __KERNEL__ + +#include <net/flow.h> +#include <net/ip6_fib.h> + +/* + * Structure for assync processing of operations on the routing + * table + */ + +struct rt6_req { + int operation; + struct rt6_info *ptr; + + struct rt6_req *next; + struct rt6_req *prev; + +#define RT_OPER_ADD 1 +#define RT_OPER_DEL 2 +}; + + +struct pol_chain { + int type; + int priority; + struct fib6_node *rules; + struct pol_chain *next; +}; + +extern struct rt6_info ip6_null_entry; + +extern void ip6_route_input(struct sk_buff *skb); + +extern struct dst_entry * ip6_route_output(struct sock *sk, + struct flowi *fl); + +extern void ip6_route_init(void); +extern void ip6_route_cleanup(void); + +extern int ipv6_route_ioctl(unsigned int cmd, void *arg); + +extern struct rt6_info * ip6_route_add(struct in6_rtmsg *rtmsg, + int *err); +extern int ip6_del_rt(struct rt6_info *); + +extern int ip6_rt_addr_add(struct in6_addr *addr, + struct device *dev); + +extern void rt6_sndmsg(int type, struct in6_addr *dst, + struct in6_addr *src, + struct in6_addr *gw, + struct device *dev, + int dstlen, int srclen, + int metric, __u32 flags); + +extern struct rt6_info *rt6_lookup(struct in6_addr *daddr, + struct in6_addr *saddr, + struct device *dev, int flags); + +/* + * support functions for ND + * + */ +extern struct rt6_info * rt6_get_dflt_router(struct in6_addr *addr, + struct device *dev); +extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr, + struct device *dev); + +extern void rt6_purge_dflt_routers(int lst_resort); + +extern struct rt6_info * rt6_redirect(struct in6_addr *dest, + struct in6_addr *saddr, + struct in6_addr *target, + struct device *dev, + int on_link); + +extern void rt6_pmtu_discovery(struct in6_addr *addr, + struct device *dev, + int pmtu); + +extern struct rt6_info * ip6_rt_copy(struct rt6_info *rt); + +/* + * Store a destination cache entry in a socket + * For UDP/RAW sockets this is done on udp_connect. + */ + +extern __inline__ void ip6_dst_store(struct sock *sk, struct dst_entry *dst) +{ + struct ipv6_pinfo *np; + struct rt6_info *rt; + + np = &sk->net_pinfo.af_inet6; + np->dst = dst; + + rt = (struct rt6_info *) dst; + + np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; +} + +#endif +#endif diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h new file mode 100644 index 000000000..e96378d77 --- /dev/null +++ b/include/net/ip_fib.h @@ -0,0 +1,133 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the Forwarding Information Base. + * + * Authors: A.N.Kuznetsov, <kuznet@ms2.inr.ac.ru> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _NET_IP_FIB_H +#define _NET_IP_FIB_H + + +struct fib_node +{ + struct fib_node *fib_next; + u32 fib_key; + struct fib_info *fib_info; + short fib_metric; + u8 fib_tos; + u8 fib_flag; +}; + +#define FIBFLG_DOWN 1 /* Ignore this node */ +#define FIBFLG_THROW 2 /* Class lookup failed */ +#define FIBFLG_REJECT 4 /* Route lookup failed */ + +#define MAGIC_METRIC 0x7FFF + +/* + * This structure contains data shared by many of routes. + */ + +struct fib_info +{ + struct fib_info *fib_next; + struct fib_info *fib_prev; + u32 fib_gateway; + struct device *fib_dev; + int fib_refcnt; + unsigned long fib_window; + unsigned fib_flags; + unsigned short fib_mtu; + unsigned short fib_irtt; +}; + +struct fib_zone +{ + struct fib_zone *fz_next; + struct fib_node **fz_hash; + int fz_nent; + int fz_divisor; + u32 fz_hashmask; + int fz_logmask; + u32 fz_mask; +}; + +struct fib_class +{ + unsigned char cl_id; + unsigned char cl_auto; + struct fib_zone *fib_zones[33]; + struct fib_zone *fib_zone_list; + int cl_users; +}; + +struct fib_rule +{ + struct fib_rule *cl_next; + struct fib_class *cl_class; + u32 cl_src; + u32 cl_srcmask; + u32 cl_dst; + u32 cl_dstmask; + u32 cl_srcmap; + u8 cl_action; + u8 cl_flags; + u8 cl_tos; + u8 cl_preference; + struct device *cl_dev; +}; + +struct fib_result +{ + struct fib_node *f; + struct fib_rule *fr; + int fm; +}; + +void ip_fib_init(void); +unsigned ip_fib_chk_addr(u32 addr); +int ip_fib_chk_default_gw(u32 addr, struct device*); + +int fib_lookup(struct fib_result *, u32 daddr, u32 src, u8 tos, struct device *devin, + struct device *devout); + +static __inline__ struct fib_info * +fib_lookup_info(u32 dst, u32 src, u8 tos, struct device *devin, + struct device *devout) +{ + struct fib_result res; + if (fib_lookup(&res, dst, src, tos, devin, devout) < 0) + return NULL; + return res.f->fib_info; +} + +static __inline__ struct device * get_gw_dev(u32 gw, struct device *dev) +{ + struct fib_info * fi; + + fi = fib_lookup_info(gw, 0, 1, &loopback_dev, dev); + if (fi) + return fi->fib_dev; + return NULL; +} + +extern int ip_rt_event(int event, struct device *dev); +extern int ip_rt_ioctl(unsigned int cmd, void *arg); +extern void ip_rt_change_broadcast(struct device *, u32); +extern void ip_rt_change_dstaddr(struct device *, u32); +extern void ip_rt_change_netmask(struct device *, u32); +extern void ip_rt_multicast_event(struct device *dev); + +extern struct device * ip_dev_find_tunnel(u32 daddr, u32 saddr); + + +#endif _NET_FIB_H diff --git a/include/net/ip_forward.h b/include/net/ip_forward.h deleted file mode 100644 index f1b532f31..000000000 --- a/include/net/ip_forward.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __NET_IP_FORWARD_H -#define __NET_IP_FORWARD_H - -#define IPFWD_FRAGMENT 1 -#define IPFWD_LASTFRAG 2 -#define IPFWD_MASQUERADED 4 -#define IPFWD_MULTICASTING 8 -#define IPFWD_MULTITUNNEL 0x10 -#define IPFWD_NOTTLDEC 0x20 - -#endif diff --git a/include/net/ipip.h b/include/net/ipip.h index bba1492ed..64ce7a29d 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -1,4 +1,8 @@ -extern int ipip_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, - __u32 daddr, unsigned short len, __u32 saddr, - int redo, struct inet_protocol *protocol); +#ifndef __NET_IPIP_H +#define __NET_IPIP_H 1 + +extern void ipip_err(struct sk_buff *skb, unsigned char*); +extern int ipip_rcv(struct sk_buff *skb, unsigned short len); + +#endif diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 5b1042927..835d54fc6 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -4,7 +4,7 @@ * Authors: * Pedro Roque <roque@di.fc.ul.pt> * - * $Id: ipv6.h,v 1.19 1996/09/24 17:04:20 roque Exp $ + * $Id: ipv6.h,v 1.6 1997/04/01 02:22:58 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,7 +16,9 @@ #define _NET_IPV6_H #include <linux/ipv6.h> +#include <asm/hardirq.h> #include <net/ndisc.h> +#include <net/flow.h> /* * NextHeader field of IPv6 header @@ -86,8 +88,29 @@ struct frag_hdr { extern struct ipv6_mib ipv6_statistics; -extern int ipv6_forwarding; /* host/router switch */ -extern int ipv6_hop_limit; /* default hop limit */ +struct ipv6_config { + int forwarding; + int hop_limit; + int accept_ra; + int accept_redirects; + + int nd_max_mcast_solicit; + int nd_max_ucast_solicit; + int nd_retrans_time; + int nd_base_reachable_time; + int nd_delay_probe_time; + + int autoconf; + int dad_transmits; + int rtr_solicits; + int rtr_solicit_interval; + int rtr_solicit_delay; + + int rt_cache_timeout; + int rt_gc_period; +}; + +extern struct ipv6_config ipv6_config; struct ipv6_frag { __u16 offset; @@ -141,6 +164,11 @@ typedef int (*inet_getfrag_t) (const void *data, extern int ipv6_addr_type(struct in6_addr *addr); +extern __inline__ int ipv6_addr_scope(struct in6_addr *addr) +{ + return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; +} + extern __inline__ int ipv6_addr_cmp(struct in6_addr *a1, struct in6_addr *a2) { return memcmp((void *) a1, (void *) a2, sizeof(struct in6_addr)); @@ -169,53 +197,18 @@ extern __inline__ int ipv6_addr_any(struct in6_addr *a) a->s6_addr32[2] | a->s6_addr32[3] ) == 0); } +extern __inline__ int gfp_any(void) +{ + int pri = GFP_KERNEL; + if (in_interrupt()) + pri = GFP_ATOMIC; + return pri; +} + /* * Prototypes exported by ipv6 */ -#if 0 -extern int ipv6_build_header(struct sk_buff *skb, - struct device *dev, - struct in6_addr *saddr_in, - struct in6_addr *daddr_in, - int proto, int len, - struct ipv6_pinfo *np); -#endif - -extern void ipv6_redo_mac_hdr(struct sk_buff *skb, - struct neighbour *neigh, - int len); - -extern int ipv6_bld_hdr_2(struct sock *sk, - struct sk_buff *skb, - struct device *dev, - struct neighbour *neigh, - struct in6_addr *saddr, - struct in6_addr *daddr, - int proto, int len); - -extern int ipv6_xmit(struct sock *sk, - struct sk_buff *skb, - struct in6_addr *saddr, - struct in6_addr *daddr, - struct ipv6_options *opt, - int proto); - -extern void ipv6_queue_xmit(struct sock *sk, - struct device *dev, - struct sk_buff *skb, - int free); - -extern int ipv6_build_xmit(struct sock *sk, - inet_getfrag_t getfrag, - const void * data, - struct in6_addr * daddr, - unsigned short int length, - struct in6_addr * saddr, - struct device *dev, - struct ipv6_options *opt, - int proto, int noblock); - /* * rcv function (called from netdevice level) */ @@ -224,16 +217,41 @@ extern int ipv6_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); -extern void ipv6_forward(struct sk_buff *skb, - struct device *dev, - int flags); +/* + * upper-layer output functions + */ +extern int ip6_xmit(struct sock *sk, + struct sk_buff *skb, + struct flowi *fl, + struct ipv6_options *opt); + +extern int ip6_nd_hdr(struct sock *sk, + struct sk_buff *skb, + struct device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr, + int proto, int len); + +extern int ip6_build_xmit(struct sock *sk, + inet_getfrag_t getfrag, + const void *data, + struct flowi *fl, + unsigned short length, + struct ipv6_options *opt, + int hlimit, int flags); + +/* + * skb processing functions + */ -#define IP6_FW_SRCRT 0x1 -#define IP6_FW_STRICT 0x2 +extern int ip6_forward(struct sk_buff *skb); +extern int ip6_input(struct sk_buff *skb); +extern int ip6_mc_input(struct sk_buff *skb); /* * Extension header (options) processing */ + extern int ipv6opt_bld_rthdr(struct sk_buff *skb, struct ipv6_options *opt, struct in6_addr *addr, @@ -255,27 +273,6 @@ extern void ipv6opt_free(struct ipv6_options *opt); /* - * socket lookup (af_inet6.c) - */ - -extern struct sock * inet6_get_sock(struct proto *prot, - struct in6_addr *loc_addr, - struct in6_addr *rmt_addr, - unsigned short loc_port, - unsigned short rmt_port); - -extern struct sock * inet6_get_sock_raw(struct sock *sk, - unsigned short num, - struct in6_addr *loc_addr, - struct in6_addr *rmt_addr); - -extern struct sock * inet6_get_sock_mcast(struct sock *sk, - unsigned short num, - unsigned short rmt_port, - struct in6_addr *loc_addr, - struct in6_addr *rmt_addr); - -/* * socket options (ipv6_sockglue.c) */ diff --git a/include/net/ipv6_route.h b/include/net/ipv6_route.h deleted file mode 100644 index aaa1ba0a2..000000000 --- a/include/net/ipv6_route.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Linux INET6 implementation - * - * Authors: - * Pedro Roque <roque@di.fc.ul.pt> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _NET_IPV6_ROUTE_H -#define _NET_IPV6_ROUTE_H - -#include <linux/ipv6_route.h> - - -#ifdef __KERNEL__ - - -struct fib6_node { - struct fib6_node *parent; - struct fib6_node *left; - struct fib6_node *right; - - struct rt6_info *leaf; - - __u16 fn_bit; /* bit key */ - __u16 fn_flags; - __u32 fn_sernum; -}; - - -struct rt6_info; - -typedef void (*rt6_output_method_t) (struct sk_buff *skb, struct rt6_info *rt); - -struct rt6_info { - struct fib6_node *fib_node; - struct rt6_info *next; - - struct in6_addr rt_dst; - - atomic_t rt_use; /* dcache references */ - atomic_t rt_ref; /* fib references */ - - struct neighbour *rt_nexthop; - struct device *rt_dev; - - rt6_output_method_t rt_output_method; - - __u16 rt_metric; - __u16 rt_prefixlen; - __u32 rt_flags; - unsigned long rt_expires; -}; - -extern struct rt6_info *default_rt_list; -extern struct rt6_info *last_resort_rt; - -struct dest_entry { - struct rt6_info rt; - - __u32 dc_irtt; - __u32 dc_window; - __u16 dc_pmtu; - - unsigned long dc_tstamp; /* for garbage collection */ - -#define dc_addr rt.rt_dst -#define dc_usecnt rt.rt_use -#define dc_nexthop rt.rt_nexthop -#define dc_flags rt.rt_flags -}; - -/* - * Structure for assync processing of operations on the routing - * table - */ - -struct rt6_req { - int operation; - struct rt6_info *ptr; - - struct rt6_req *next; - struct rt6_req *prev; - -#define RT_OPER_ADD 1 -#define RT_OPER_DEL 2 -}; - -struct rt6_statistics { - __u32 fib_nodes; - __u32 fib_route_nodes; - __u32 fib_rt_alloc; - __u32 fib_rt_entries; - __u32 fib_dc_alloc; -}; - -#define RTN_ROOT 0x0001 /* root node */ -#define RTN_BACKTRACK 0x0002 /* backtrack point */ -#define RTN_TAG 0x0010 - -/* - * Values for destination cache garbage colection - * These are wild guesses for now... - */ - -#define DC_WATER_MARK 512 -#define DC_SHORT_TIMEOUT (5*HZ) -#define DC_LONG_TIMEOUT (15*HZ) - -#define DC_TIME_RUN (5*HZ) -#define DC_TIME_RETRY HZ - -#define RT6_FILTER_NONE 0 -#define RT6_FILTER_RTNODES 1 -/* - * Prototypes - */ - -/* - * check/obtain destination cache from routing table - */ - -extern struct dest_entry * ipv6_dst_check(struct dest_entry *dc, - struct in6_addr * daddr, - __u32 sernum, int flags); - -extern struct dest_entry * ipv6_dst_route(struct in6_addr * daddr, - struct device *src_dev, - int flags); - -extern void ipv6_dst_unlock(struct dest_entry *dest); - -extern struct rt6_info * fibv6_lookup(struct in6_addr *addr, - struct device *dev, - int flags); - -/* - * user space set/del route - */ - -extern int ipv6_route_ioctl(unsigned int cmd, void *arg); - - -extern void ipv6_route_init(void); -extern void ipv6_route_cleanup(void); - -extern void rt6_ifdown(struct device *dev); - -extern int ipv6_route_add(struct in6_rtmsg *rt); - -extern int fib6_del_rt(struct rt6_info *rt); - -extern void rt6_sndmsg(__u32 type, struct in6_addr *dst, - struct in6_addr *gw, __u16 plen, - struct device *dev, - __u16 metric, __u16 flags); -/* - * ICMP interface - */ - -extern struct rt6_info * ipv6_rt_redirect(struct device *dev, - struct in6_addr *dest, - struct in6_addr *target, - int on_link); - -extern void rt6_handle_pmtu(struct in6_addr *addr, - int pmtu); -/* - * - */ - -extern struct fib6_node routing_table; -extern struct rt6_statistics rt6_stats; - -static __inline__ void rt_release(struct rt6_info *rt) -{ - atomic_dec(&rt->rt_ref); - if ((rt->rt_use | rt->rt_ref) == 0) - { - if (rt->rt_nexthop) - { - ndisc_dec_neigh(rt->rt_nexthop); - } - - if (rt->rt_flags & RTI_DCACHE) - { - rt6_stats.fib_dc_alloc--; - } - rt6_stats.fib_rt_alloc--; - kfree(rt); - } -} - -#endif - -#endif diff --git a/include/net/ipx.h b/include/net/ipx.h index f23800901..374a899ba 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -26,7 +26,7 @@ typedef struct #define ipx_broadcast_node "\377\377\377\377\377\377" #define ipx_this_node "\0\0\0\0\0\0" -typedef struct ipx_packet +struct ipxhdr { unsigned short ipx_checksum __attribute__ ((packed)); #define IPX_NO_CHECKSUM 0xFFFF @@ -41,10 +41,7 @@ typedef struct ipx_packet #define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast [Not supported] */ ipx_address ipx_dest __attribute__ ((packed)); ipx_address ipx_source __attribute__ ((packed)); -} ipx_packet; - - -typedef struct sock ipx_socket; +}; #include <net/ipxcall.h> extern int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); @@ -62,7 +59,7 @@ typedef struct ipx_interface { /* socket support */ unsigned short if_sknum; - ipx_socket *if_sklist; + struct sock *if_sklist; /* administrative overhead */ int if_ipx_offset; diff --git a/include/net/lapb.h b/include/net/lapb.h new file mode 100644 index 000000000..f06583cee --- /dev/null +++ b/include/net/lapb.h @@ -0,0 +1,150 @@ +#ifndef _LAPB_H +#define _LAPB_H +#include <linux/lapb.h> + +#define LAPB_SLOWHZ 10 /* Run timing at 1/10 second */ + +#define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */ + +#define LAPB_ACK_PENDING_CONDITION 0x01 +#define LAPB_REJECT_CONDITION 0x02 +#define LAPB_PEER_RX_BUSY_CONDITION 0x04 + +/* Control field templates */ +#define LAPB_I 0x00 /* Information frames */ +#define LAPB_S 0x01 /* Supervisory frames */ +#define LAPB_U 0x03 /* Unnumbered frames */ + +#define LAPB_RR 0x01 /* Receiver ready */ +#define LAPB_RNR 0x05 /* Receiver not ready */ +#define LAPB_REJ 0x09 /* Reject */ + +#define LAPB_SABM 0x2F /* Set Asynchronous Balanced Mode */ +#define LAPB_SABME 0x6F /* Set Asynchronous Balanced Mode Extended */ +#define LAPB_DISC 0x43 /* Disconnect */ +#define LAPB_DM 0x0F /* Disconnected mode */ +#define LAPB_UA 0x63 /* Unnumbered acknowledge */ +#define LAPB_FRMR 0x87 /* Frame reject */ + +#define LAPB_ILLEGAL 0x100 /* Impossible to be a real frame type */ + +#define LAPB_SPF 0x10 /* Poll/final bit for standard LAPB */ +#define LAPB_EPF 0x01 /* Poll/final bit for extended LAPB */ + +#define LAPB_FRMR_W 0x01 /* Control field invalid */ +#define LAPB_FRMR_X 0x02 /* I field invalid */ +#define LAPB_FRMR_Y 0x04 /* I field too long */ +#define LAPB_FRMR_Z 0x08 /* Invalid N(R) */ + +#define LAPB_POLLOFF 0 +#define LAPB_POLLON 1 + +/* LAPB C-bit */ +#define LAPB_COMMAND 1 +#define LAPB_RESPONSE 2 + +#define LAPB_ADDR_A 0x03 +#define LAPB_ADDR_B 0x01 +#define LAPB_ADDR_C 0x0F +#define LAPB_ADDR_D 0x07 + +/* Define Link State constants. */ +enum { + LAPB_STATE_0, /* Disconnected State */ + LAPB_STATE_1, /* Awaiting Connection State */ + LAPB_STATE_2, /* Awaiting Disconnection State */ + LAPB_STATE_3, /* Data Transfer State */ + LAPB_STATE_4 /* Frame Reject State */ +}; + +#define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE) +#define LAPB_DEFAULT_WINDOW 7 /* Window=7 */ +#define LAPB_DEFAULT_T1 (5 * LAPB_SLOWHZ) /* T1=5s */ +#define LAPB_DEFAULT_T2 (1 * LAPB_SLOWHZ) /* T2=1s */ +#define LAPB_DEFAULT_N2 20 /* N2=20 */ + +#define LAPB_SMODULUS 8 +#define LAPB_EMODULUS 128 + +/* + * Information about the current frame. + */ +struct lapb_frame { + unsigned short type; /* Parsed type */ + unsigned short nr, ns; /* N(R), N(S) */ + unsigned char cr; /* Command/Response */ + unsigned char pf; /* Poll/Final */ + unsigned char control[2]; /* Original control data*/ +}; + +/* + * The per LAPB connection control structure. + */ +typedef struct lapb_cb { + struct lapb_cb *next; + void *token; + + /* Link status fields */ + unsigned int mode; + unsigned char state; + unsigned short vs, vr, va; + unsigned char condition; + unsigned short n2, n2count; + unsigned short t1, t2; + unsigned short t1timer, t2timer; + + /* Internal control information */ + struct sk_buff_head input_queue; + struct sk_buff_head write_queue; + struct sk_buff_head ack_queue; + unsigned char window; + struct timer_list timer; + struct lapb_register_struct callbacks; + + /* FRMR control information */ + struct lapb_frame frmr_data; + unsigned char frmr_type; +} lapb_cb; + +/* lapb_iface.c */ +extern void lapb_connect_confirmation(lapb_cb *, int); +extern void lapb_connect_indication(lapb_cb *, int); +extern void lapb_disconnect_confirmation(lapb_cb *, int); +extern void lapb_disconnect_indication(lapb_cb *, int); +extern int lapb_data_indication(lapb_cb *, struct sk_buff *); +extern int lapb_data_transmit(lapb_cb *, struct sk_buff *); + +/* lapb_in.c */ +extern void lapb_data_input(lapb_cb *, struct sk_buff *); + +/* lapb_out.c */ +extern void lapb_kick(lapb_cb *); +extern void lapb_transmit_buffer(lapb_cb *, struct sk_buff *, int); +extern void lapb_establish_data_link(lapb_cb *); +extern void lapb_enquiry_response(lapb_cb *); +extern void lapb_timeout_response(lapb_cb *); +extern void lapb_check_iframes_acked(lapb_cb *, unsigned short); +extern void lapb_check_need_response(lapb_cb *, int, int); + +/* lapb_subr.c */ +extern void lapb_clear_queues(lapb_cb *); +extern void lapb_frames_acked(lapb_cb *, unsigned short); +extern void lapb_requeue_frames(lapb_cb *); +extern int lapb_validate_nr(lapb_cb *, unsigned short); +extern void lapb_decode(lapb_cb *, struct sk_buff *, struct lapb_frame *); +extern void lapb_send_control(lapb_cb *, int, int, int); +extern void lapb_transmit_frmr(lapb_cb *); + +/* lapb_timer.c */ +extern void lapb_set_timer(lapb_cb *); + +/* + * Debug levels. + * 0 = Off + * 1 = State Changes + * 2 = Packets I/O and State Changes + * 3 = Hex dumps, Packets I/O and State Changes. + */ +#define LAPB_DEBUG 0 + +#endif diff --git a/include/net/lapbcall.h b/include/net/lapbcall.h new file mode 100644 index 000000000..825e7f2c7 --- /dev/null +++ b/include/net/lapbcall.h @@ -0,0 +1,2 @@ +/* Separate to keep compilation of protocols.c simpler */ +extern void lapb_proto_init(struct net_proto *pro); diff --git a/include/net/llc.h b/include/net/llc.h new file mode 100644 index 000000000..37abe50af --- /dev/null +++ b/include/net/llc.h @@ -0,0 +1,134 @@ +#include <linux/skbuff.h> + +#define LLC_MODULE + +typedef struct llc_struct llc; +typedef struct llc_struct *llcptr; + +/* + * LLC private data area structure. + */ + +struct llc_struct +{ + char eye[4]; /* To recognize llc area in dump */ + int retry_count; /* LLC link state variables */ + unsigned char s_flag; + unsigned char p_flag; + unsigned char f_flag; + unsigned char data_flag; + unsigned char cause_flag; + unsigned char vs; /* Send state variable */ + unsigned char vr; /* Receive state variable */ + unsigned char remote_busy; + unsigned char state; /* Current state of type2 llc procedure */ + int n1; /* Maximum number of bytes in I pdu 7.8.2 */ + int n2; /* Naximum number of retransmissions 7.8.2 */ + unsigned char k; /* Transmit window size 7.8.4, tw in IBM doc*/ + unsigned char rw; /* Receive window size */ + struct + { + /* + * FRMR_RSP info field structure: 5.4.2.3.5 p55 + */ + + unsigned char cntl1; + unsigned char cntl2; + unsigned char vs; + unsigned char vr_cr; + unsigned char xxyz; + } frmr_info_fld; + + /* + * Timers in 7.8.1 page 78 + */ + +#define P_TIMER 0 +#define REJ_TIMER 1 +#define ACK_TIMER 2 +#define BUSY_TIMER 3 + unsigned long timer_expire_time[4]; + unsigned char timer_state[4]; /* The state of each timer */ +#define TIMER_IDLE 0 +#define TIMER_RUNNING 1 +#define TIMER_EXPIRED 2 + unsigned long timer_interval[4]; + struct timer_list tl[4]; + + /* + * Client entry point, called by the LLC. + */ + + void (*llc_event)(struct llc_struct *); + + /* + * Mux and Demux variables + */ + + char * client_data; /* Pointer to clients context */ + unsigned char local_sap; + unsigned char remote_sap ; + char remote_mac[MAX_ADDR_LEN]; /* MAC address of remote session partner */ + int remote_mac_len; /* Actual length of mac address */ + int mac_offset; /* Source mac offset in skb */ + struct device *dev; /* Device we are attached to */ + + unsigned char llc_mode; /* See doc 7.1 on p70 */ +#define MODE_ADM 1 +#define MODE_ABM 2 + + int llc_callbacks; /* Pending callbacks */ +#define LLC_CONN_INDICATION 1 /* We have to ensure the names don't */ +#define LLC_CONN_CONFIRM 2 /* mix up with the 802 state table */ +#define LLC_DATA_INDIC 4 +#define LLC_DISC_INDICATION 8 +#define LLC_RESET_INDIC_LOC 16 +#define LLC_RESET_INDIC_REM 32 +#define LLC_RST_CONFIRM 64 +#define LLC_FRMR_RECV 128 +#define LLC_FRMR_SENT 256 +#define LLC_REMOTE_BUSY 512 +#define LLC_REMOTE_NOTBUSY 1024 +#define LLC_TEST_INDICATION 2048 +#define LLC_XID_INDICATION 4096 +#define LLC_UI_DATA 8192 + + struct sk_buff *inc_skb; /* Saved data buffer for indications */ + + struct sk_buff_head rtq; /* Retransmit queue */ + struct sk_buff_head atq; /* Await transit queue */ + + unsigned char xid_count; + + struct llc_struct *nextllc; /* ptr to next llc struct in proto chain */ +}; + +#define ADD_TO_RTQ(skb) skb_queue_tail(&lp->rtq,skb) +#define ADD_TO_ATQ(skb) skb_queue_tail(&lp->atq,skb) + +void llc_cancel_timers(llcptr lp); +int llc_decode_frametype(frameptr fr); +llcptr llc_find(void); +int llc_free_acknowledged_skbs(llcptr lp, unsigned char ack); +void llc_handle_xid_indication( char *chsp, short int ll, char *xid_data); +void llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, char type); +void llc_add_to_queue(struct sk_buff *skb, struct sk_buff **f, struct sk_buff **b); +void llc_process_otype2_frame(llcptr lp, struct sk_buff *skb, char type); +struct sk_buff *llc_pull_from_atq(llcptr lp); +int llc_resend_ipdu(llcptr lp, unsigned char ack_nr, unsigned char type, char p); +void llc_sendpdu(llcptr lp, char type, char pf, int data_len, char *pdu_data); +void llc_sendipdu(llcptr lp, char type, char pf, struct sk_buff *skb); +void llc_start_timer(llcptr lp, int t); +void llc_stop_timer(llcptr lp, int t); +void llc_timer_expired(llcptr lp, int t); +int llc_validate_seq_nos(llcptr lp, frameptr fr); + +int llc_data_request(llcptr lp, struct sk_buff *skb); +void llc_unit_data_request(llcptr lp, int ll, char * data); +void llc_disconnect_request(llcptr lp); +void llc_connect_request(llcptr lp); +void llc_xid_request(llcptr lp, char opt, int data_len, char *pdu_data); +void llc_test_request(llcptr lp, int data_len, char *pdu_data); + +int register_cl2llc_client(llcptr llc, const char *device, void (*ops)(llcptr), u8 *rmac, u8 ssap, u8 dsap); +void unregister_cl2llc_client(llcptr lp); diff --git a/include/net/llc_frame.h b/include/net/llc_frame.h new file mode 100644 index 000000000..e8fb198d1 --- /dev/null +++ b/include/net/llc_frame.h @@ -0,0 +1,98 @@ +/* if_ether.h needed for definition of ETH_DATA_LEN and ETH_ALEN + */ +#include "linux/if_ether.h" + +/* frame layout based on par3.2 "LLC PDU format" + */ +typedef union { /* pdu layout from pages 40 & 44 */ + struct { /* general header, all pdu types */ + unsigned dsap : 8; /* dest service access point */ + unsigned ssap : 8; /* source service access point */ + unsigned f1 : 1; /* I- U- or S- format id bits */ + unsigned f2 : 1; + unsigned : 6; + unsigned : 8; + } pdu_hdr; + struct { + char dummy1[2]; /* dsap + ssap */ + char byte1; + char byte2; + } pdu_cntl; /* unformatted control bytes */ + struct { /* header of an Information pdu */ + unsigned char dummy2[2]; + unsigned : 1; + unsigned ns : 7; + unsigned i_pflag : 1; /* poll/final bit */ + unsigned nr : 7; /* N(R) */ + unsigned char is_info[ ETH_DATA_LEN ]; + } i_hdr; + struct { /* header of a Supervisory pdu */ + unsigned char dummy3[2]; + unsigned : 2; + unsigned ss : 2; /* supervisory function bits */ + unsigned : 4; + unsigned s_pflag : 1; /* poll/final bit */ + unsigned nr : 7; /* N(R) */ + } s_hdr; + +/* when accessing the P/F bit or the N(R) field there's no need to distinguish + I pdus from S pdus i_pflag and s_pflag / i_nr and s_nr map to the same + physical location. + */ + struct { /* header of an Unnumbered pdu */ + unsigned char dummy4[2]; + unsigned : 2; + unsigned mm1 : 2; /* modifier function part1 */ + unsigned u_pflag : 1; /* P/F for U- pdus */ + unsigned mm2 : 3; /* modifier function part2 */ + unsigned char u_info[ ETH_DATA_LEN-1]; + } u_hdr; + struct { /* mm field in an Unnumbered pdu */ + unsigned char dummy5[2]; + unsigned : 2; + unsigned mm : 6; /* must be masked to get ridd of P/F ! */ + } u_mm; + +} frame_type, *frameptr; + +/* frame format test macros: */ + +#define IS_UFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & ( (fr)->pdu_hdr.f2) ) + +#define IS_IFRAME( fr ) ( !( (fr)->pdu_hdr.f1) ) + +#define IS_SFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & !( (fr)->pdu_hdr.f2) ) + +#define IS_RSP( fr ) ( fr->pdu_hdr.ssap & 0x01 ) + + +/* The transition table, the _encode tables and some tests in the + source code depend on the numeric order of these values. + Think twice before changing. + */ + +/* frame names for TYPE 2 operation: */ +#define I_CMD 0 +#define RR_CMD 1 +#define RNR_CMD 2 +#define REJ_CMD 3 +#define DISC_CMD 4 +#define SABME_CMD 5 +#define I_RSP 6 +#define RR_RSP 7 +#define RNR_RSP 8 +#define REJ_RSP 9 +#define UA_RSP 10 +#define DM_RSP 11 +#define FRMR_RSP 12 + +/* junk frame name: */ +#define BAD_FRAME 13 +#define NO_FRAME 13 + +/* frame names for TYPE 1 operation: */ +#define UI_CMD 14 +#define XID_CMD 15 +#define TEST_CMD 16 +#define XID_RSP 17 +#define TEST_RSP 18 diff --git a/include/net/llc_name.h b/include/net/llc_name.h new file mode 100644 index 000000000..72128719f --- /dev/null +++ b/include/net/llc_name.h @@ -0,0 +1,7 @@ +char *frame_names[] = + {"I_CMD","RR_CMD","RNR_CMD","REJ_CMD","DISC_CMD", + "SABME_CMD","I_RSP","RR_RSP","RNR_RSP","REJ_RSP", + "UA_RSP","DM_RSP","FRMR_RSP","BAD_FRAME","UI_CMD", + "XID_CMD","TEST_CMD","XID_RSP","TEST_RSP" +}; + diff --git a/include/net/llc_state.h b/include/net/llc_state.h new file mode 100644 index 000000000..bb18e9bd1 --- /dev/null +++ b/include/net/llc_state.h @@ -0,0 +1,4 @@ +char *state_names[] = { + "ADM","CONN","RESET_WAIT","RESET_CHECK","SETUP", + "RESET","D_CONN","ERROR","NORMAL" +}; diff --git a/include/net/llccall.h b/include/net/llccall.h new file mode 100644 index 000000000..07013ba31 --- /dev/null +++ b/include/net/llccall.h @@ -0,0 +1,3 @@ +/* Separate to keep compilation of protocols.c simpler */ +extern void llc_init(struct net_proto *pro); + diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 3605997e7..9173a0eae 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -22,12 +22,12 @@ #define NDISC_QUEUE_LEN 3 -#define NCF_NOARP 0x01 /* no ARP needed on this device */ -#define NCF_SUBNET 0x02 /* NC entry for subnet */ -#define NCF_INVALID 0x04 -#define NCF_DELAY_EXPIRED 0x08 /* time to move to PROBE */ -#define NCF_ROUTER 0x10 /* neighbour is a router */ -#define NCF_HHVALID 0x20 /* Hardware header is valid */ +#define NCF_NOARP 0x0100 /* no ARP needed on this device */ +#define NCF_SUBNET 0x0200 /* NC entry for subnet */ +#define NCF_INVALID 0x0400 +#define NCF_DELAY_EXPIRED 0x0800 /* time to move to PROBE */ +#define NCF_ROUTER 0x1000 /* neighbour is a router */ +#define NCF_HHVALID 0x2000 /* Hardware header is valid */ /* * ICMP codes for neighbour discovery messages @@ -64,42 +64,35 @@ #include <linux/skbuff.h> #include <linux/netdevice.h> #include <linux/icmpv6.h> +#include <net/neighbour.h> #include <asm/atomic.h> /* * neighbour cache entry * used by neighbour discovery module - * as similar functions of "struct hh_cache" used in ipv4 */ -struct neighbour { - struct in6_addr addr; /* next hop addr */ - __u8 len; /* prefix len */ - __u8 type; /* {unicast, multicast} */ - - struct device * dev; - __u8 flags; +struct nd_neigh { + struct neighbour neigh; + struct in6_addr ndn_addr; /* next hop addr */ + __u8 ndn_plen, /* prefix len */ + ndn_type, /* {unicast, multicast} */ + ndn_nud_state, + ndn_probes; - __u8 hh_data[MAX_ADDR_LEN]; /* cached hdr */ - __u8 *h_dest; /* dest addr */ + unsigned long ndn_expires; /* timer expires at */ - struct sk_buff_head arp_queue; /* packets waiting for ND to - finish */ - atomic_t refcnt; - __u8 nud_state; - __u8 probes; - __u32 tstamp; /* last reachable conf */ - - unsigned long expires; /* timer expires at */ - - struct neighbour *next; /* for hash chaining */ - struct neighbour *prev; /* for hash chaining */ +#define ndn_refcnt neigh.refcnt +#define ndn_tstamp neigh.lastused +#define ndn_dev neigh.dev +#define ndn_flags neigh.flags +#define ndn_ha neigh.ha }; struct nd_msg { - struct icmpv6hdr icmph; - struct in6_addr target; + struct icmp6hdr icmph; + struct in6_addr target; struct { __u8 opt_type; __u8 opt_len; @@ -108,7 +101,7 @@ struct nd_msg { }; struct ra_msg { - struct icmpv6hdr icmph; + struct icmp6hdr icmph; __u32 reachable_time; __u32 retrans_timer; }; @@ -124,18 +117,16 @@ struct ndisc_statistics { __u32 res_failed; /* address resolution failures */ }; -extern struct neighbour * ndisc_get_neigh(struct device *dev, - struct in6_addr *addr); +extern struct neighbour * ndisc_find_neigh(struct device *dev, + struct in6_addr *addr); extern void ndisc_validate(struct neighbour *neigh); -extern void ndisc_init(struct proto_ops *ops); +extern void ndisc_init(struct net_proto_family *ops); +extern struct neighbour* ndisc_get_neigh(struct device *dev, + struct in6_addr *addr); extern void ndisc_cleanup(void); -extern int ndisc_eth_resolv(unsigned char *, - struct device *, - struct sk_buff *); - extern int ndisc_rcv(struct sk_buff *skb, struct device *dev, struct in6_addr *saddr, @@ -156,9 +147,8 @@ extern void ndisc_send_rs(struct device *dev, struct in6_addr *saddr, struct in6_addr *daddr); -extern int (*ndisc_eth_hook) (unsigned char *, - struct device *, - struct sk_buff *); +extern int ndisc_eth_resolv(unsigned char *, + struct sk_buff *); extern void ndisc_forwarding_on(void); extern void ndisc_forwarding_off(void); @@ -170,13 +160,20 @@ extern void ndisc_send_redirect(struct sk_buff *skb, struct rt6_info * dflt_rt_lookup(void); extern unsigned long nd_rand_seed; -extern int ipv6_random(void); +extern unsigned long ipv6_random(void); + +/* + * IGMP + */ +extern void igmp6_init(struct net_proto_family *ops); +extern int igmp6_event_query(struct sk_buff *skb, + struct icmp6hdr *hdr, + int len); -static __inline__ void ndisc_dec_neigh(struct neighbour *neigh) -{ - atomic_dec(&neigh->refcnt); -} +extern int igmp6_event_report(struct sk_buff *skb, + struct icmp6hdr *hdr, + int len); #endif /* __KERNEL__ */ diff --git a/include/net/neighbour.h b/include/net/neighbour.h new file mode 100644 index 000000000..ec2331522 --- /dev/null +++ b/include/net/neighbour.h @@ -0,0 +1,174 @@ +#ifndef _NET_NEIGHBOUR_H +#define _NET_NEIGHBOUR_H + +/* + * Generic neighbour manipulation + * + * authors: + * Pedro Roque <roque@di.fc.ul.pt> + */ + +#ifdef __KERNEL__ + +#include <asm/atomic.h> +#include <linux/skbuff.h> + +/* + * flags + * + */ +#define NTF_COMPLETE 0x02 +#define NTF_PERMANENT 0x04 + +struct neighbour { + struct neighbour *next; + struct neighbour *prev; + struct neigh_table *tbl; + struct device *dev; + unsigned long lastused; + unsigned long flags; + unsigned char ha[MAX_ADDR_LEN]; + struct hh_cache *hh; + atomic_t refcnt; + struct neigh_ops *ops; + struct sk_buff_head arp_queue; + char primary_key[0]; +}; + +struct neigh_ops { + int family; + unsigned int (*hash)(void *primary_key); + int (*resolve)(unsigned char *h_dest, + struct sk_buff *skb); + void (*destructor)(struct neighbour *); +}; + +extern struct neighbour *neigh_alloc(int size, struct neigh_ops *); + +/* + * Neighbour references + * + * When neighbour pointers are passed to "client" code the + * reference count is increased. The count is 0 if the node + * is only referenced by the corresponding table. + * + * Nodes cannot be unlinked from the table if their + * reference count != 0. + * + * i.e. you can't reclaim a neighbour if it is being used by a + * dst_cache or routing entry - hopefully those will react + * to memory shortage and GC their unused entries + */ + + +static __inline__ void neigh_release(struct neighbour *neigh) +{ + if (atomic_dec_and_test(&neigh->refcnt)) + neigh->lastused = jiffies; +} + +static __inline__ struct neighbour * neighbour_clone(struct neighbour *neigh) +{ + if (neigh) + atomic_inc(&neigh->refcnt); + return neigh; +} + +#define NT_MASK_QUEUE 0x01 +#define NT_MASK_GC 0x02 + +/* + * neighbour table manipulation + */ + +struct neigh_table { + int tbl_size; /* num. of hash buckets */ + int tbl_entries; /* entry count */ + struct neighbour **hash_buckets; + atomic_t tbl_lock; + unsigned int tbl_bh_mask; /* bh mask */ + struct neigh_ops *neigh_ops; + struct neighbour *request_queue; /* pending inserts */ +}; + +extern void neigh_table_init(struct neigh_table *tbl, + struct neigh_ops *ops, + int size); +extern void neigh_table_destroy(struct neigh_table *tbl); + +extern void neigh_table_run_bh(struct neigh_table *tbl); + +extern void neigh_table_ins(struct neigh_table *tbl, + struct neighbour *neigh); + +extern void neigh_queue_ins(struct neigh_table *tbl, + struct neighbour *neigh); + +extern void neigh_unlink(struct neighbour *neigh); + +extern struct neighbour * neigh_lookup(struct neigh_table *tbl, + void *pkey, int key_len, + struct device *dev); + +extern void neigh_destroy(struct neighbour *neigh); + +static __inline__ void neigh_insert(struct neigh_table *tbl, + struct neighbour *neigh) +{ + start_bh_atomic(); + if (atomic_read(&tbl->tbl_lock) == 1) + { + neigh_table_ins(tbl, neigh); + } + else + { + tbl->tbl_bh_mask |= NT_MASK_QUEUE; + neigh_queue_ins(tbl, neigh); + } + end_bh_atomic(); +} + + + +typedef int (*ntbl_examine_t) (struct neighbour *neigh, void *arg); + +/* + * examine every element of a neighbour table. + * For every neighbour the callback function will be called. + * + * parameters: + * max : max bucket index (<= tbl_size, 0 all) + * filter : (neigh->flags & (~filter)) -> call func + * args : opaque pointer + * + * return values + * 0 nop + * !0 unlink node from table and destroy it + */ + +extern void ntbl_walk_table(struct neigh_table *tbl, + ntbl_examine_t func, + unsigned long filter, + int max, void *args); + +static __inline__ void neigh_table_lock(struct neigh_table *tbl) +{ + atomic_inc(&tbl->tbl_lock); +} + +extern void neigh_tbl_run_bh(struct neigh_table *tbl); + +static __inline__ void neigh_table_unlock(struct neigh_table *tbl) +{ + start_bh_atomic(); + if (atomic_dec_and_test(&tbl->tbl_lock) && tbl->tbl_bh_mask) + { + neigh_tbl_run_bh(tbl); + } + end_bh_atomic(); +} + +#endif +#endif + + diff --git a/include/net/netbeui.h b/include/net/netbeui.h new file mode 100644 index 000000000..417a27e2c --- /dev/null +++ b/include/net/netbeui.h @@ -0,0 +1,150 @@ +/* + * NetBEUI data structures + */ + +#ifndef __NET_NETBEUI_H +#define __NET_NETBEUI_H + + +#define NB_NAME_LEN 16 + +/* + * Used to keep lists of netbeui sessions + */ + +struct nb_ses +{ + struct nb_ses *next; + struct nb_nam *name; + struct nb_link *parent; /* Owner link */ + struct sock *sk; +}; + +/* + * A netbeui link + */ + +struct nb_link +{ + struct llc llc; /* Must be first */ + u8 mac[6]; /* Mac address of remote */ + struct device *dev; /* Device we heard him on */ + struct nb_ses *sessions;/* Netbeui sessions on this LLC link */ + struct wait_queue *wait;/* Wait queue for this netbios LLC */ + int busy; /* Track the LLC busy state */ + int state; /* Link state */ +#define NETBEUI_OPEN 1 /* Up and going */ +#define NETBEUI_CONNWAIT 2 /* Waiting to come up */ +#define NETBEUI_DISCWAIT 3 /* Waiting to drop and recover */ +#define NETBEUI_DEADWAIT 4 /* Trying to die */ +}; + + +/* + * Netbios name defence list + */ + +struct nb_name +{ + struct nb_name *next; /* Chain */ + struct device *dev; /* Device */ + char name[NB_NAME_LEN]; /* Object Name */ + int state; /* Name State */ +#define NB_NAME_ACQUIRE 1 /* We are trying to get a name */ +#define NB_NAME_COLLIDE 2 /* Name collided - we failed */ +#define NB_OURS 3 /* We own the name */ +#define NB_NAME_OTHER 4 /* Name found - owned by other */ +#define NB_NAME_GET 5 /* Trying to allocate a name */ +#define NB_STATE 7 /* State bits */ +#define NB_NAME_GROUP 8 /* Group name bit */ + int ours; /* We own this name */ + int users; /* Number of nb_ses's to this name */ + struct timer_list timer; /* Our timer */ + int timer_mode; /* Timer mode */ +#define NB_TIMER_ACQUIRE 1 /* Expiry means we got our name */ +#define NB_TIMER_COLLIDE 2 /* Expire a collided record */ +#define NB_TIMER_DROP 3 /* Drop a learned record */ +}; + + +/* + * LLC link manager + */ + +extern struct nb_link *netbeui_find_link(u8 macaddr); +extern struct nb_link *netbeui_create_link(u8 macaddr); +extern int netbeui_destroy_link(u8 macaddr); + +/* + * Namespace manager + */ + +extern struct nb_name *netbeui_find_name(char *name); +extern struct nb_name *netbeui_add_name(char *name, int ours); +extern struct nb_name *netbeui_lookup_name(char *name); +extern int nb_delete_name(struct nb_name *name); + +/* + * NetBEUI Protocol items + */ + +#define ADD_GROUP_NAME_QUERY 0x00 +#define ADD_NAME_QUERY 0x01 +#define NAME_IN_CONFLICT 0x02 +#define STATUS_QUERY 0x03 +#define TERMINATE_TRACE 0x07 +#define DATAGRAM 0x08 +#define DATAGRAM_BROADCAST 0x09 +#define NAME_QUERY 0x0A +#define ADD_NAME_RESPONSE 0x0D +#define NAME_RECOGNIZED 0x0E +#define STATUS_RESPONSE 0x0F +#define TERMINATE_TRACE2 0x13 +#define DATA_ACK 0x14 +#define DATA_FIRST_MIDDLE 0x15 +#define DATA_ONLY_LAST 0x16 +#define SESSION_CONFIRM 0x17 +#define SESSION_END 0x18 +#define SESSION_INITIALIZE 0x19 +#define NO_RECEIVE 0x1A +#define RECEIVE_OUTSTANDING 0x1B +#define RECEIVE_CONTINUE 0x1C +#define SESSION_ALIVE 0x1F + +#define NB_TRANSMIT_COUNT 6 +#define NB_TRANSMIT_TIMEOUT (HZ/2) + +#define NB_DESCRIM_1 0xEF +#define NB_DESCRIM_2 0xFF + +struct nb_dgram_pkt +{ + __u16 length; + __u8 descrim1; + __u8 descrim2; + __u8 command; + __u8 option1; + __u16 option2; + __u16 tx_seq; + __u16 rx_seq; + __u8 dest[NB_NAME_LEN]; + __u8 src[NB_NAME_LEN]; +}; + +struct nb_sess_pkt +{ + __u16 length; + __u8 descrim1; + __u8 descrim2; + __u8 command; + __u8 option1; + __u16 option2; + __u16 tx_seq; + __u16 rx_seq; + __u8 dnum; + __u8 snum; +}; + +#define NO_SEQ 0 + +#endif diff --git a/include/net/netbeuicall.h b/include/net/netbeuicall.h new file mode 100644 index 000000000..5176f82bf --- /dev/null +++ b/include/net/netbeuicall.h @@ -0,0 +1,2 @@ +/* Separate to keep compilation of protocols.c simpler */ +extern void netbeui_proto_init(struct net_proto *pro); diff --git a/include/net/netlink.h b/include/net/netlink.h index f0b9c9d74..b9e91a3d3 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -2,14 +2,17 @@ #define __NET_NETLINK_H #define NET_MAJOR 36 /* Major 18 is reserved for networking */ +/* so.... ^^ is this 36? */ +/* and the things below... */ #define MAX_LINKS 16 /* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved */ /* 4-7 are psi0-psi3 8 is arpd 9 is ppp */ /* 10 is for IPSEC <John Ioannidis> */ /* 11 IPv6 route updates */ /* 12 is for firewall trapout */ + #define MAX_QBYTES 32768 /* Maximum bytes in the queue */ -#include <linux/config.h> +#include <linux/netlink.h> extern int netlink_attach(int unit, int (*function)(int,struct sk_buff *skb)); extern int netlink_donothing(int, struct sk_buff *skb); @@ -17,6 +20,44 @@ extern void netlink_detach(int unit); extern int netlink_post(int unit, struct sk_buff *skb); extern int init_netlink(void); +/* + * skb should fit one page. This choice is good for headerless malloc. + */ +#define NLMSG_GOODSIZE (PAGE_SIZE - ((sizeof(struct sk_buff)+0xF)&~0xF)) + +#define NLMSG_RECOVERY_TIMEO (HZ/2) /* If deleivery was failed, + retry after */ + +struct nlmsg_ctl +{ + struct timer_list nlmsg_timer; + struct sk_buff *nlmsg_skb; /* Partially built skb */ + int nlmsg_unit; + int nlmsg_delay; /* Time to delay skb send*/ + int nlmsg_maxsize; /* Maximal message size */ + int nlmsg_force; /* post immediately */ + unsigned long nlmsg_overrun_start; /* seqno starting lossage*/ + unsigned long nlmsg_overrun_end; /* the last lost message */ + char nlmsg_overrun; /* overrun flag */ +}; + +void* nlmsg_send(struct nlmsg_ctl*, unsigned long type, int len, + unsigned long seq, unsigned long pid); +void nlmsg_transmit(struct nlmsg_ctl*); + +extern __inline__ void nlmsg_ack(struct nlmsg_ctl* ctl, unsigned long seq, + unsigned long pid, int err) +{ + int *r; + + start_bh_atomic(); + r = nlmsg_send(ctl, NLMSG_ACK, sizeof(r), seq, pid); + if (r) + *r = err; + end_bh_atomic(); +} + + #define NETLINK_ROUTE 0 /* Routing/device hook */ #define NETLINK_SKIP 1 /* Reserved for ENskip */ #define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ @@ -25,11 +66,9 @@ extern int init_netlink(void); #define NETLINK_ARPD 8 #define NETLINK_IPSEC 10 /* IPSEC */ #define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */ -#define NETLINK_ +#define NETLINK_IP6_FW 13 +/* Wouldn't this suffice instead of the confusion at the top of + this file? i.e. 3 is firewall or ppp... */ +/* #define MAX_LINKS 16 */ -#ifdef CONFIG_RTNETLINK -extern void ip_netlink_msg(unsigned long, __u32, __u32, __u32, short, short, char *); -#else -#define ip_netlink_msg(a,b,c,d,e,f,g) -#endif #endif diff --git a/include/net/netrom.h b/include/net/netrom.h index ce398d23c..a3ce51ca3 100644 --- a/include/net/netrom.h +++ b/include/net/netrom.h @@ -3,62 +3,70 @@ * * Jonathan Naylor G4KLX 9/4/95 */ - + #ifndef _NETROM_H #define _NETROM_H #include <linux/netrom.h> -#define NR_T1CLAMPLO (1 * PR_SLOWHZ) /* If defined, clamp at 1 second **/ -#define NR_T1CLAMPHI (300 * PR_SLOWHZ) /* If defined, clamp at 30 seconds **/ +#define NR_SLOWHZ 10 /* Run timing at 1/10 second */ + +#define NR_NETWORK_LEN 15 +#define NR_TRANSPORT_LEN 5 -#define NR_NETWORK_LEN 15 -#define NR_TRANSPORT_LEN 5 - -#define NR_PROTO_IP 0x0C +#define NR_PROTO_IP 0x0C -#define NR_PROTOEXT 0x00 -#define NR_CONNREQ 0x01 -#define NR_CONNACK 0x02 -#define NR_DISCREQ 0x03 -#define NR_DISCACK 0x04 -#define NR_INFO 0x05 -#define NR_INFOACK 0x06 +#define NR_PROTOEXT 0x00 +#define NR_CONNREQ 0x01 +#define NR_CONNACK 0x02 +#define NR_DISCREQ 0x03 +#define NR_DISCACK 0x04 +#define NR_INFO 0x05 +#define NR_INFOACK 0x06 -#define NR_CHOKE_FLAG 0x80 -#define NR_NAK_FLAG 0x40 -#define NR_MORE_FLAG 0x20 +#define NR_CHOKE_FLAG 0x80 +#define NR_NAK_FLAG 0x40 +#define NR_MORE_FLAG 0x20 /* Define Link State constants. */ +enum { + NR_STATE_0, + NR_STATE_1, + NR_STATE_2, + NR_STATE_3 +}; -#define NR_STATE_0 0 -#define NR_STATE_1 1 -#define NR_STATE_2 2 -#define NR_STATE_3 3 - -#define NR_DEFAULT_T1 (120 * PR_SLOWHZ) /* Outstanding frames - 120 seconds */ -#define NR_DEFAULT_T2 (5 * PR_SLOWHZ) /* Response delay - 5 seconds */ -#define NR_DEFAULT_N2 3 /* Number of Retries - 3 */ -#define NR_DEFAULT_T4 (180 * PR_SLOWHZ) /* Busy Delay - 180 seconds */ -#define NR_DEFAULT_IDLE (20* 60 * PR_SLOWHZ) /* No Activuty Timeout - 900 seconds*/ -#define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */ -#define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */ -#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */ -#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */ -#define NR_MODULUS 256 -#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */ -#define NR_DEFAULT_PACLEN 236 /* Default Packet Length - 236 */ +#define NR_COND_ACK_PENDING 0x01 +#define NR_COND_REJECT 0x02 +#define NR_COND_PEER_RX_BUSY 0x04 +#define NR_COND_OWN_RX_BUSY 0x08 + +#define NR_DEFAULT_T1 (120 * NR_SLOWHZ) /* Outstanding frames - 120 seconds */ +#define NR_DEFAULT_T2 (5 * NR_SLOWHZ) /* Response delay - 5 seconds */ +#define NR_DEFAULT_N2 3 /* Number of Retries - 3 */ +#define NR_DEFAULT_T4 (180 * NR_SLOWHZ) /* Busy Delay - 180 seconds */ +#define NR_DEFAULT_IDLE (20* 60 * NR_SLOWHZ) /* No Activuty Timeout - 900 seconds*/ +#define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */ +#define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */ +#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */ +#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */ +#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */ +#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */ + +#define NR_MODULUS 256 +#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */ +#define NR_MAX_PACKET_SIZE 236 /* Maximum Packet Length - 236 */ typedef struct { ax25_address user_addr, source_addr, dest_addr; struct device *device; unsigned char my_index, my_id; unsigned char your_index, your_id; - unsigned char state, condition, bpqext, hdrincl; + unsigned char state, condition, bpqext, hdrincl, window; unsigned short vs, vr, va, vl; unsigned char n2, n2count; - unsigned short t1, t2, t4, idle, rtt; + unsigned short t1, t2, t4, idle; unsigned short t1timer, t2timer, t4timer, idletimer; - unsigned short fraglen, paclen; + unsigned short fraglen; struct sk_buff_head ack_queue; struct sk_buff_head reseq_queue; struct sk_buff_head frag_queue; @@ -74,6 +82,7 @@ struct nr_neigh { unsigned char locked; unsigned short count; unsigned int number; + unsigned char failed; }; struct nr_route { @@ -85,7 +94,7 @@ struct nr_route { struct nr_node { struct nr_node *next; ax25_address callsign; - char mnemonic[7]; + char mnemonic[7]; unsigned char which; unsigned char count; struct nr_route routes[3]; @@ -101,8 +110,8 @@ extern int sysctl_netrom_transport_acknowledge_delay; extern int sysctl_netrom_transport_busy_delay; extern int sysctl_netrom_transport_requested_window_size; extern int sysctl_netrom_transport_no_activity_timeout; -extern int sysctl_netrom_transport_packet_length; extern int sysctl_netrom_routing_control; +extern int sysctl_netrom_link_fails_count; extern int nr_rx_frame(struct sk_buff *, struct device *); extern void nr_destroy_socket(struct sock *); @@ -143,8 +152,6 @@ extern int nr_validate_nr(struct sock *, unsigned short); extern int nr_in_rx_window(struct sock *, unsigned short); extern void nr_write_internal(struct sock *, int); extern void nr_transmit_dm(struct sk_buff *); -extern unsigned short nr_calculate_t1(struct sock *); -extern void nr_calculate_rtt(struct sock *); /* nr_timer.c */ extern void nr_set_timer(struct sock *); diff --git a/include/net/protocol.h b/include/net/protocol.h index 979298832..3e60c1b31 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -34,39 +34,36 @@ /* This is used to register protocols. */ -struct inet_protocol { - int (*handler)(struct sk_buff *skb, struct device *dev, - struct options *opt, __u32 daddr, - unsigned short len, __u32 saddr, - int redo, struct inet_protocol *protocol); - void (*err_handler)(int type, int code, unsigned char *buff, - __u32 info, __u32 daddr, __u32 saddr, - struct inet_protocol *protocol, int len); - struct inet_protocol *next; - unsigned char protocol; - unsigned char copy:1; - void *data; - const char *name; +struct inet_protocol +{ + int (*handler)(struct sk_buff *skb, unsigned short len); + void (*err_handler)(struct sk_buff *skb, unsigned char *dp); + struct inet_protocol *next; + unsigned char protocol; + unsigned char copy:1; + void *data; + const char *name; }; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -struct inet6_protocol { - int (*handler)(struct sk_buff *skb, struct device *dev, - struct in6_addr *saddr, - struct in6_addr *daddr, - struct ipv6_options *opt, - unsigned short len, - int redo, struct inet6_protocol *protocol); +struct inet6_protocol +{ + int (*handler)(struct sk_buff *skb, struct device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr, + struct ipv6_options *opt, + unsigned short len, + int redo, struct inet6_protocol *protocol); - void (*err_handler)(int type, int code, unsigned char *buff, - __u32 info, struct in6_addr *saddr, - struct in6_addr *daddr, - struct inet6_protocol *protocol); - struct inet6_protocol *next; - unsigned char protocol; - unsigned char copy:1; - void *data; - const char *name; + void (*err_handler)(int type, int code, unsigned char *buff, + __u32 info, struct in6_addr *saddr, + struct in6_addr *daddr, + struct inet6_protocol *protocol); + struct inet6_protocol *next; + unsigned char protocol; + unsigned char copy:1; + void *data; + const char *name; }; #endif @@ -78,12 +75,12 @@ extern struct inet6_protocol *inet6_protocol_base; extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; #endif -extern void inet_add_protocol(struct inet_protocol *prot); -extern int inet_del_protocol(struct inet_protocol *prot); +extern void inet_add_protocol(struct inet_protocol *prot); +extern int inet_del_protocol(struct inet_protocol *prot); #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -extern void inet6_add_protocol(struct inet6_protocol *prot); -extern int inet6_del_protocol(struct inet6_protocol *prot); +extern void inet6_add_protocol(struct inet6_protocol *prot); +extern int inet6_del_protocol(struct inet6_protocol *prot); #endif #endif /* _PROTOCOL_H */ diff --git a/include/net/raw.h b/include/net/raw.h index 4b4248790..064b5bf7a 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -21,14 +21,17 @@ extern struct proto raw_prot; -extern void raw_err(int type, int code, unsigned char *header, __u32 daddr, - __u32 saddr, struct inet_protocol *protocol); -extern int raw_recvfrom(struct sock *sk, unsigned char *to, - int len, int noblock, unsigned flags, - struct sockaddr_in *sin, int *addr_len); -extern int raw_read(struct sock *sk, unsigned char *buff, - int len, int noblock, unsigned flags); -extern int raw_rcv(struct sock *, struct sk_buff *, struct device *, - __u32, __u32); +extern void raw_err(struct sock *, struct sk_buff *); +extern int raw_rcv(struct sock *, struct sk_buff *); + +/* Note: v4 ICMP wants to get at this stuff, if you change the + * hashing mechanism, make sure you update icmp.c as well. + */ +#define RAWV4_HTABLE_SIZE MAX_INET_PROTOS +extern struct sock *raw_v4_htable[RAWV4_HTABLE_SIZE]; + + +extern struct sock *raw_v4_lookup(struct sock *sk, unsigned short num, + unsigned long raddr, unsigned long laddr); #endif /* _RAW_H */ diff --git a/include/net/rawv6.h b/include/net/rawv6.h index 30ecc7962..36373719f 100644 --- a/include/net/rawv6.h +++ b/include/net/rawv6.h @@ -2,6 +2,14 @@ #define _NET_RAWV6_H #ifdef __KERNEL__ + +#define RAWV6_HTABLE_SIZE MAX_INET_PROTOS +extern struct sock *raw_v6_htable[RAWV6_HTABLE_SIZE]; + + +extern struct sock *raw_v6_lookup(struct sock *sk, unsigned short num, + struct in6_addr *loc_addr, struct in6_addr *rmt_addr); + extern int rawv6_rcv(struct sk_buff *skb, struct device *dev, struct in6_addr *saddr, diff --git a/include/net/rose.h b/include/net/rose.h index 84d4e9654..2c9565d8a 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -3,20 +3,22 @@ * * Jonathan Naylor G4KLX 25/8/96 */ - + #ifndef _ROSE_H #define _ROSE_H #include <linux/rose.h> +#define ROSE_SLOWHZ 10 /* Run timing at 1/10 second */ + #define ROSE_ADDR_LEN 5 #define ROSE_MIN_LEN 3 -#define GFI 0x10 -#define Q_BIT 0x80 -#define D_BIT 0x40 -#define M_BIT 0x10 - +#define ROSE_GFI 0x10 +#define ROSE_Q_BIT 0x80 +#define ROSE_D_BIT 0x40 +#define ROSE_M_BIT 0x10 + #define ROSE_CALL_REQUEST 0x0B #define ROSE_CALL_ACCEPTED 0x0F #define ROSE_CLEAR_REQUEST 0x13 @@ -38,32 +40,41 @@ /* Define Link State constants. */ -#define ROSE_STATE_0 0 /* Ready */ -#define ROSE_STATE_1 1 /* Awaiting Call Accepted */ -#define ROSE_STATE_2 2 /* Awaiting Clear Confirmation */ -#define ROSE_STATE_3 3 /* Data Transfer */ -#define ROSE_STATE_4 4 /* Awaiting Reset Confirmation */ - -#define ROSE_DEFAULT_T0 (180 * PR_SLOWHZ) /* Default T10 T20 value */ -#define ROSE_DEFAULT_T1 (200 * PR_SLOWHZ) /* Default T11 T21 value */ -#define ROSE_DEFAULT_T2 (180 * PR_SLOWHZ) /* Default T12 T22 value */ -#define ROSE_DEFAULT_T3 (180 * PR_SLOWHZ) /* Default T13 T23 value */ -#define ROSE_DEFAULT_IDLE (20 * 60 * PR_SLOWHZ) /* Default No Activity value */ -#define ROSE_DEFAULT_WINDOW 2 /* Default Window Size */ -#define ROSE_MODULUS 8 -#define ROSE_MAX_WINDOW_SIZE 7 /* Maximum Window Allowable */ -#define ROSE_PACLEN 128 /* Default Packet Length */ - -#define FAC_NATIONAL 0x00 -#define FAC_CCITT 0x0F - -#define FAC_NATIONAL_RAND 0x7F -#define FAC_NATIONAL_FLAGS 0x3F -#define FAC_NATIONAL_DEST_DIGI 0xE9 -#define FAC_NATIONAL_SRC_DIGI 0xEB - -#define FAC_CCITT_DEST_NSAP 0xC9 -#define FAC_CCITT_SRC_NSAP 0xCB +enum { + ROSE_STATE_0, /* Ready */ + ROSE_STATE_1, /* Awaiting Call Accepted */ + ROSE_STATE_2, /* Awaiting Clear Confirmation */ + ROSE_STATE_3, /* Data Transfer */ + ROSE_STATE_4 /* Awaiting Reset Confirmation */ +}; + +#define ROSE_DEFAULT_T0 (180 * ROSE_SLOWHZ) /* Default T10 T20 value */ +#define ROSE_DEFAULT_T1 (200 * ROSE_SLOWHZ) /* Default T11 T21 value */ +#define ROSE_DEFAULT_T2 (180 * ROSE_SLOWHZ) /* Default T12 T22 value */ +#define ROSE_DEFAULT_T3 (180 * ROSE_SLOWHZ) /* Default T13 T23 value */ +#define ROSE_DEFAULT_HB (5 * ROSE_SLOWHZ) /* Default Holdback value */ +#define ROSE_DEFAULT_IDLE (20 * 60 * ROSE_SLOWHZ) /* Default No Activity value */ +#define ROSE_DEFAULT_ROUTING 1 /* Default routing flag */ +#define ROSE_DEFAULT_FAIL_TIMEOUT (120 * ROSE_SLOWHZ) /* Time until link considered usable */ + +#define ROSE_MODULUS 8 +#define ROSE_MAX_WINDOW_SIZE 2 /* Maximum Window Allowable */ +#define ROSE_MAX_PACKET_SIZE 128 /* Maximum Packet Length */ + +#define ROSE_COND_ACK_PENDING 0x01 +#define ROSE_COND_PEER_RX_BUSY 0x02 +#define ROSE_COND_OWN_RX_BUSY 0x04 + +#define FAC_NATIONAL 0x00 +#define FAC_CCITT 0x0F + +#define FAC_NATIONAL_RAND 0x7F +#define FAC_NATIONAL_FLAGS 0x3F +#define FAC_NATIONAL_DEST_DIGI 0xE9 +#define FAC_NATIONAL_SRC_DIGI 0xEB + +#define FAC_CCITT_DEST_NSAP 0xC9 +#define FAC_CCITT_SRC_NSAP 0xCB struct rose_neigh { struct rose_neigh *next; @@ -74,14 +85,14 @@ struct rose_neigh { unsigned int number; int restarted; struct sk_buff_head queue; - unsigned short t0, t0timer; + unsigned short t0timer, ftimer; struct timer_list timer; }; struct rose_node { struct rose_node *next; rose_address address; - unsigned char which; + unsigned short mask; unsigned char count; struct rose_neigh *neighbour[3]; }; @@ -104,21 +115,24 @@ typedef struct { unsigned char state, condition, hdrincl; unsigned short vs, vr, va, vl; unsigned short timer; - unsigned short t1, t2, t3, idle; + unsigned short t1, t2, t3, hb, idle; unsigned short fraglen; - struct sk_buff_head ack_queue; struct sk_buff_head frag_queue; struct sock *sk; /* Backlink to socket */ } rose_cb; /* af_rose.c */ +extern ax25_address rose_callsign; extern int sysctl_rose_restart_request_timeout; extern int sysctl_rose_call_request_timeout; extern int sysctl_rose_reset_request_timeout; extern int sysctl_rose_clear_request_timeout; extern int sysctl_rose_no_activity_timeout; +extern int sysctl_rose_ack_hold_back_timeout; extern int sysctl_rose_routing_control; +extern int sysctl_rose_link_fail_timeout; extern int rosecmp(rose_address *, rose_address *); +extern int rosecmpm(rose_address *, rose_address *, unsigned short); extern char *rose2asc(rose_address *); extern struct sock *rose_find_socket(unsigned int, struct device *); extern unsigned int rose_new_lci(struct device *); @@ -135,6 +149,7 @@ extern int rose_init(struct device *); extern int rose_process_rx_frame(struct sock *, struct sk_buff *); /* rose_link.c */ +extern void rose_link_set_timer(struct rose_neigh *); extern void rose_link_rx_restart(struct sk_buff *, struct rose_neigh *, unsigned short); extern void rose_transmit_restart_request(struct rose_neigh *); extern void rose_transmit_restart_confirmation(struct rose_neigh *); @@ -165,8 +180,6 @@ extern void rose_rt_free(void); /* rose_subr.c */ extern void rose_clear_queues(struct sock *); -extern void rose_frames_acked(struct sock *, unsigned short); -extern void rose_requeue_frames(struct sock *); extern int rose_validate_nr(struct sock *, unsigned short); extern void rose_write_internal(struct sock *, int); extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); diff --git a/include/net/route.h b/include/net/route.h index de59bda48..d309ab63f 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -14,9 +14,6 @@ * Alan Cox : Support for TCP parameters. * Alexey Kuznetsov: Major changes for new routing code. * - * FIXME: - * Make atomic ops more generic and hide them in asm/... - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -25,25 +22,12 @@ #ifndef _ROUTE_H #define _ROUTE_H -#include <linux/config.h> +#include <net/ip_fib.h> +#include <net/dst.h> -/* - * 0 - no debugging messages - * 1 - rare events and bugs situations (default) - * 2 - trace mode. - */ -#define RT_CACHE_DEBUG 0 #define RT_HASH_DIVISOR 256 -#define RT_CACHE_SIZE_MAX 256 - -#define RTZ_HASH_DIVISOR 256 - -#if RT_CACHE_DEBUG >= 2 -#define RTZ_HASHING_LIMIT 0 -#else -#define RTZ_HASHING_LIMIT 16 -#endif +#define RT_CACHE_MAX_SIZE 256 /* * Maximal time to live for unused entry. @@ -51,127 +35,140 @@ #define RT_CACHE_TIMEOUT (HZ*300) /* + * Cache invalidations can be delayed by: + */ +#define RT_FLUSH_DELAY (2*HZ) + +#define RT_REDIRECT_NUMBER 9 +#define RT_REDIRECT_LOAD (HZ/50) /* 20 msec */ +#define RT_REDIRECT_SILENCE (RT_REDIRECT_LOAD<<(RT_REDIRECT_NUMBER+1)) + /* 20sec */ + +#define RT_ERROR_LOAD (1*HZ) + + +/* * Prevents LRU trashing, entries considered equivalent, * if the difference between last use times is less then this number. */ -#define RT_CACHE_BUBBLE_THRESHOLD (HZ*5) +#define RT_CACHE_BUBBLE_THRESHOLD (5*HZ) #include <linux/route.h> -#ifdef __KERNEL__ -#define RTF_LOCAL 0x8000 -#endif - struct rtable { - struct rtable *rt_next; - __u32 rt_dst; - __u32 rt_src; - __u32 rt_gateway; - atomic_t rt_refcnt; - atomic_t rt_use; - unsigned long rt_window; - atomic_t rt_lastuse; - struct hh_cache *rt_hh; - struct device *rt_dev; - unsigned short rt_flags; - unsigned short rt_mtu; - unsigned short rt_irtt; - unsigned char rt_tos; -}; + union + { + struct dst_entry dst; + struct rtable *rt_next; + } u; -extern void ip_rt_flush(struct device *dev); -extern void ip_rt_update(int event, struct device *dev); -extern void ip_rt_redirect(__u32 src, __u32 dst, __u32 gw, struct device *dev); -extern struct rtable *ip_rt_slow_route(__u32 daddr, int local); -extern int rt_get_info(char * buffer, char **start, off_t offset, int length, int dummy); -extern int rt_cache_get_info(char *buffer, char **start, off_t offset, int length, int dummy); -extern int ip_rt_ioctl(unsigned int cmd, void *arg); -extern int ip_rt_new(struct rtentry *rt); -extern int ip_rt_kill(struct rtentry *rt); -extern void ip_rt_check_expire(void); -extern void ip_rt_advice(struct rtable **rp, int advice); + unsigned rt_flags; -extern void ip_rt_run_bh(void); -extern atomic_t ip_rt_lock; -extern unsigned ip_rt_bh_mask; -extern struct rtable *ip_rt_hash_table[RT_HASH_DIVISOR]; + u32 rt_dst; /* Path destination */ + u32 rt_src; /* Path source */ + struct device *rt_src_dev; /* Path source device */ -extern __inline__ void ip_rt_fast_lock(void) -{ - atomic_inc(&ip_rt_lock); -} + /* Info on neighbour */ + u32 rt_gateway; -extern __inline__ void ip_rt_fast_unlock(void) -{ - atomic_dec(&ip_rt_lock); -} + /* Cache lookup keys */ + struct + { + u32 dst; + u32 src; + struct device *src_dev; + struct device *dst_dev; + u8 tos; + } key; + + /* Miscellaneous cached information */ + u32 rt_spec_dst; /* RFC1122 specific destination */ + u32 rt_src_map; + u32 rt_dst_map; + + /* ICMP statistics */ + unsigned long last_error; + unsigned long errors; +}; -extern __inline__ void ip_rt_unlock(void) -{ - if (atomic_dec_and_test(&ip_rt_lock) && ip_rt_bh_mask) - ip_rt_run_bh(); -} -extern __inline__ unsigned ip_rt_hash_code(__u32 addr) -{ - unsigned tmp = addr + (addr>>16); - return (tmp + (tmp>>8)) & 0xFF; -} +#define RTF_IFBRD (RTF_UP|RTF_MAGIC|RTF_LOCAL|RTF_BROADCAST) +#define RTF_IFLOCAL (RTF_UP|RTF_MAGIC|RTF_LOCAL|RTF_INTERFACE) +#define RTF_IFPREFIX (RTF_UP|RTF_MAGIC|RTF_INTERFACE) +/* + * Flags not visible at user level. + */ +#define RTF_INTERNAL 0xFFFF8000 /* to get RTF_MAGIC as well... */ + +/* + * Flags saved in FIB. + */ +#define RTF_FIB (RTF_UP|RTF_GATEWAY|RTF_REJECT|RTF_THROW|RTF_STATIC|\ + RTF_XRESOLVE|RTF_NOPMTUDISC|RTF_NOFORWARD|RTF_INTERNAL) -extern __inline__ void ip_rt_put(struct rtable * rt) -#ifndef MODULE +extern void ip_rt_init(void); +extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw, + u32 src, u8 tos, struct device *dev); +extern void ip_rt_check_expire(void); +extern void ip_rt_advice(struct rtable **rp, int advice); +extern void rt_cache_flush(int how); +extern int ip_route_output(struct rtable **, u32 dst, u32 src, u8 tos, struct device *devout); +extern int ip_route_output_dev(struct rtable **, u32 dst, u32 src, u8 tos, int); +extern int ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct device *devin); +extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu); +extern void ip_rt_send_redirect(struct sk_buff *skb); + +static __inline__ void ip_rt_put(struct rtable * rt) { if (rt) - atomic_dec(&rt->rt_refcnt); + dst_release(&rt->u.dst); } -#else -; -#endif - -#ifdef CONFIG_KERNELD -extern struct rtable * ip_rt_route(__u32 daddr, int local); -#else -extern __inline__ struct rtable * ip_rt_route(__u32 daddr, int local) -#ifndef MODULE + +static __inline__ char rt_tos2priority(u8 tos) { - struct rtable * rth; + if (tos & IPTOS_LOWDELAY) + return SOPRI_INTERACTIVE; + if (tos & (IPTOS_THROUGHPUT|IPTOS_MINCOST)) + return SOPRI_BACKGROUND; + return SOPRI_NORMAL; +} - ip_rt_fast_lock(); - for (rth=ip_rt_hash_table[ip_rt_hash_code(daddr)^local]; rth; rth=rth->rt_next) - { - if (rth->rt_dst == daddr) - { - rth->rt_lastuse = jiffies; - atomic_inc(&rth->rt_use); - atomic_inc(&rth->rt_refcnt); - ip_rt_unlock(); - return rth; - } - } - return ip_rt_slow_route (daddr, local); +static __inline__ int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos) +{ + int err; + err = ip_route_output(rp, dst, src, tos, NULL); + if (err || (dst && src)) + return err; + dst = (*rp)->rt_dst; + src = (*rp)->rt_src; + ip_rt_put(*rp); + *rp = NULL; + return ip_route_output(rp, dst, src, tos, NULL); } -#else -; -#endif -#endif -extern __inline__ struct rtable * ip_check_route(struct rtable ** rp, - __u32 daddr, int local) +static __inline__ void ip_ll_header(struct sk_buff *skb) { - struct rtable * rt = *rp; - - if (!rt || rt->rt_dst != daddr || !(rt->rt_flags&RTF_UP) - || ((local==1)^((rt->rt_flags&RTF_LOCAL) != 0))) - { - ip_rt_put(rt); - rt = ip_rt_route(daddr, local); - *rp = rt; - } - return rt; -} + struct rtable *rt = (struct rtable*)skb->dst; + struct device *dev = rt->u.dst.dev; + struct hh_cache *hh = rt->u.dst.hh; + int hh_len = dev->hard_header_len; + + skb->dev = dev; + skb->arp = 1; + skb->protocol = htons(ETH_P_IP); + + if (hh) { + memcpy(skb_push(skb, hh_len), hh->hh_data, hh_len); + skb->arp = hh->hh_uptodate; + } else if (dev->hard_header && + dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, 0)<0) + skb->arp = 0; + + skb->mac.raw = skb->data; +} #endif /* _ROUTE_H */ diff --git a/include/net/scm.h b/include/net/scm.h new file mode 100644 index 000000000..d8bb8d1eb --- /dev/null +++ b/include/net/scm.h @@ -0,0 +1,69 @@ +#ifndef __LINUX_NET_SCM_H +#define __LINUX_NET_SCM_H + +/* Well, we should have at least one descriptor open + * to accept passed FDs 8) + */ +#define SCM_MAX_FD (OPEN_MAX-1) + +struct scm_fp_list +{ + int count; + struct file *fp[SCM_MAX_FD]; +}; + +struct scm_cookie +{ + struct ucred creds; /* Skb credentials */ + struct scm_fp_list *fp; /* Passed files */ + unsigned long seq; /* Connection seqno */ + struct socket *sock; /* Passed socket */ +}; + +extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm); +extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm); +extern void __scm_destroy(struct scm_cookie *scm); +extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); + +static __inline__ void scm_destroy(struct scm_cookie *scm) +{ + if (scm && scm->fp) + __scm_destroy(scm); +} + +static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm) +{ + memset(scm, 0, sizeof(*scm)); + scm->creds.uid = current->uid; + scm->creds.gid = current->gid; + scm->creds.pid = current->pid; + scm->sock = sock; + if (msg->msg_controllen <= 0) + return 0; + return __scm_send(sock, msg, scm); +} + +static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm, int flags) +{ + if (!msg->msg_control) + { + if (sock->passcred || scm->fp) + msg->msg_flags |= MSG_CTRUNC; + scm_destroy(scm); + return; + } + + if (sock->passcred) + put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds); + + if (!scm->fp) + return; + + scm_detach_fds(msg, scm); +} + + +#endif __LINUX_NET_SCM_H + diff --git a/include/net/sock.h b/include/net/sock.h index eeb364159..61936854f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -22,6 +22,7 @@ * Alan Cox : New fields for options * Pauline Middelink : identd support * Alan Cox : Eliminate low level recv/recvfrom + * David S. Miller : New socket lookup architecture. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -33,7 +34,6 @@ #include <linux/config.h> #include <linux/timer.h> -#include <linux/ip.h> /* struct options */ #include <linux/in.h> /* struct sockaddr_in */ #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) @@ -50,7 +50,7 @@ #include <linux/skbuff.h> /* struct sk_buff */ #include <net/protocol.h> /* struct inet_protocol */ #if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) -#/* notyet */include <net/x25.h> +#include <net/x25.h> #endif #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) #include <net/ax25.h> @@ -74,10 +74,6 @@ #include <asm/atomic.h> -/* Think big (also on some systems a byte is faster) */ -#define SOCK_ARRAY_SIZE 256 - - /* * The AF_UNIX specific socket options */ @@ -87,9 +83,11 @@ struct unix_opt int family; char * name; int locks; + struct unix_address *addr; struct inode * inode; struct semaphore readsem; struct sock * other; + struct sock ** list; int marksweep; #define MARKED 1 int inflight; @@ -148,12 +146,15 @@ struct ipv6_pinfo __u8 recvsrcrt:1, rxinfo:1, + rxhlim:1, + hopopts:1, + dstopts:1, mc_loop:1, - unused:4; + unused:2; - /* device for outgoing mcast packets */ + /* device for outgoing packets */ - struct device *mc_if; + struct device *oif; struct ipv6_mc_socklist *ipv6_mc_list; /* @@ -163,8 +164,8 @@ struct ipv6_pinfo * (ex. PMTU) */ - struct dest_entry *dest; - __u32 dc_sernum; + struct dst_entry *dst; + __u32 dst_cookie; struct ipv6_options *opt; }; @@ -178,6 +179,7 @@ struct raw6_opt { #endif /* IPV6 */ + struct tcp_opt { /* @@ -196,6 +198,7 @@ struct tcp_opt __u32 rcv_wup; /* rcv_nxt on last window update sent */ + __u32 fin_seq; /* XXX This one should go, we don't need it. -DaveM */ __u32 srtt; /* smothed round trip time << 3 */ __u32 mdev; /* medium deviation */ @@ -206,6 +209,28 @@ struct tcp_opt */ __u32 snd_cwnd; /* Sending congestion window */ __u32 snd_ssthresh; /* Slow start size threshold */ + __u16 snd_cwnd_cnt; + __u16 max_window; + +/* + * Options received (usually on last packet, some only on SYN packets). + */ + char tstamp_ok, /* TIMESTAMP seen on SYN packet */ + sack_ok; /* SACK_PERM seen on SYN packet */ + char saw_tstamp; /* Saw TIMESTAMP on last packet */ + __u16 in_mss; /* MSS option received from sender */ + __u8 snd_wscale; /* Window scaling received from sender */ + __u8 rcv_wscale; /* Window scaling to send to receiver */ + __u32 rcv_tsval; /* Time stamp value */ + __u32 rcv_tsecr; /* Time stamp echo reply */ + __u32 ts_recent; /* Time stamp to echo next */ + __u32 ts_recent_stamp;/* Time we stored ts_recent (for aging) */ + __u32 last_ack_sent; /* last ack we sent */ + int sacks; /* Number of SACK blocks if any */ + __u32 left_sack[4]; /* Left edges of blocks */ + __u32 right_sack[4]; /* Right edges of blocks */ + int tcp_header_len; /* Bytes of tcp header to send */ + /* * Timers used by the TCP protocol layer */ @@ -216,17 +241,21 @@ struct tcp_opt struct timer_list retransmit_timer; /* Resend (no ack) */ __u32 basertt; /* Vegas baseRTT */ + __u32 packets_out; /* Packets which are "in flight" */ + __u32 window_clamp; /* XXX Document this... -DaveM */ + __u8 pending; /* pending events */ __u8 delayed_acks; - __u8 dup_acks; + __u8 dup_acks; /* Consequetive duplicate acks seen from other end */ + __u8 retransmits; __u32 lrcvtime; /* timestamp of last received data packet */ __u32 rcv_tstamp; /* timestamp of last received packet */ __u32 iat_mdev; /* interarrival time medium deviation */ __u32 iat; /* interarrival time */ __u32 ato; /* delayed ack timeout */ + __u32 high_seq; /* highest sequence number sent by onset of congestion */ - __u32 high_seq; /* * new send pointers */ @@ -237,11 +266,6 @@ struct tcp_opt * fast retransmit */ /* - * pending events - */ - __u8 pending; - -/* * Header prediction flags * 0x5?10 << 16 + snd_wnd in net byte order */ @@ -251,6 +275,7 @@ struct tcp_opt __u32 probes_out; /* unanswered 0 window probes */ struct open_request *syn_wait_queue; + struct open_request **syn_wait_last; struct tcp_func *af_specific; }; @@ -289,40 +314,50 @@ struct tcp_opt * } */ +/* Define this to get the sk->debug debugging facility. */ +#define SOCK_DEBUGGING +#ifdef SOCK_DEBUGGING +#define SOCK_DEBUG(sk, msg...) if((sk) && ((sk)->debug)) printk(KERN_DEBUG ## msg) +#else +#define SOCK_DEBUG(sk, msg...) do { } while (0) +#endif + /* * TCP will start to use the new protinfo while *still using the old* fields */ struct sock { - struct options *opt; + /* This must be first. */ + struct sock *sklist_next; + struct sock *sklist_prev; + atomic_t wmem_alloc; atomic_t rmem_alloc; unsigned long allocation; /* Allocation mode */ + + /* The following stuff should probably move to the tcp private area */ __u32 write_seq; __u32 copied_seq; - __u32 fin_seq; __u32 syn_seq; __u32 urg_seq; __u32 urg_data; - int users; /* user count */ + unsigned char delayed_acks; + /* End of block to move */ + + int sock_readers; /* user count */ - unsigned char delayed_acks, - dup_acks; /* * Not all are volatile, but some are, so we * might as well say they all are. */ volatile char dead, urginline, - intr, - blog, done, reuse, keepopen, linger, destroy, - ack_timed, no_check, zapped, /* In ax25 & ipx means not linked */ broadcast, @@ -330,21 +365,21 @@ struct sock bsdism; unsigned long lingertime; int proc; + struct sock *next; - struct sock *prev; /* Doubly linked chain.. */ + struct sock **pprev; + struct sock *bind_next; + struct sock **bind_pprev; + struct sock *prev; + int hashent; struct sock *pair; - struct sk_buff * send_head; - struct sk_buff * send_tail; - struct sk_buff_head back_log; - struct sk_buff *partial; - struct timer_list partial_timer; - atomic_t retransmits; struct sk_buff_head write_queue, receive_queue, - out_of_order_queue; + out_of_order_queue, + error_queue; unsigned short family; struct proto *prot; @@ -354,28 +389,20 @@ struct sock __u32 saddr; /* Sending source */ __u32 rcv_saddr; /* Bound address */ - unsigned short max_unacked; + struct dst_entry *dst_cache; + unsigned short max_unacked; - unsigned short bytes_rcv; /* * mss is min(mtu, max_window) */ unsigned short mtu; /* mss negotiated in the syn's */ unsigned short mss; /* current eff. mss - can change */ unsigned short user_mss; /* mss requested by user in ioctl */ - unsigned short max_window; - unsigned long window_clamp; - unsigned int ssthresh; unsigned short num; - unsigned short cong_window; - unsigned short cong_count; - atomic_t packets_out; unsigned short shutdown; - unsigned short window; /* used by netrom/ax.25 */ - #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) union { struct ipv6_pinfo af_inet6; @@ -388,13 +415,7 @@ struct sock struct raw6_opt tp_raw; #endif } tp_pinfo; -/* - * currently backoff isn't used, but I'm maintaining it in case - * we want to go back to a backoff formula that needs it - */ -/* - unsigned short backoff; - */ + int err, err_soft; /* Soft holds errors that don't cause failure but are the cause of a persistent failure not just @@ -409,7 +430,12 @@ struct sock int sndbuf; unsigned short type; unsigned char localroute; /* Route locally only */ - + struct ucred peercred; + + /* What the user has tried to set with the security API */ + short authentication; + short encryption; + short encrypt_net; /* * This is where all the private (optional) areas that don't * overlap will eventually live. @@ -449,19 +475,17 @@ struct sock */ int ip_ttl; /* TTL setting */ int ip_tos; /* TOS */ + unsigned ip_cmsg_flags; struct tcphdr dummy_th; - struct timer_list keepalive_timer; /* TCP keepalive hack */ - struct timer_list retransmit_timer; /* TCP retransmit timer */ - struct timer_list delack_timer; /* TCP delayed ack timer */ - int ip_xmit_timeout; /* Why the timeout is running */ - struct rtable *ip_route_cache; /* Cached output route */ + struct ip_options *opt; unsigned char ip_hdrincl; /* Include headers ? */ -#ifdef CONFIG_IP_MULTICAST - int ip_mc_ttl; /* Multicasting TTL */ - int ip_mc_loop; /* Loopback */ - char ip_mc_name[MAX_ADDR_LEN];/* Multicast device name */ + __u8 ip_mc_ttl; /* Multicasting TTL */ + __u8 ip_mc_loop; /* Loopback */ + __u8 ip_recverr; + __u8 ip_pmtudisc; + int ip_mc_index; /* Multicast device index */ + __u32 ip_mc_addr; struct ip_mc_socklist *ip_mc_list; /* Group array */ -#endif /* * This part is used for the timeout functions (timer.c). @@ -469,8 +493,8 @@ struct sock int timeout; /* What are we waiting for? */ struct timer_list timer; /* This is the TIME_WAIT/receive timer - * when we are doing IP - */ + * when we are doing IP + */ struct timeval stamp; /* @@ -478,6 +502,11 @@ struct sock */ struct socket *socket; + + /* + * RPC layer private data + */ + void *user_data; /* * Callbacks @@ -492,19 +521,6 @@ struct sock struct sk_buff *skb); }; -#if 0 -/* - * Inet protocol options - */ -struct inet_options { - __u8 version; - union { - struct options opt_v4; - struct ipv6_options opt_v6; - } u; -}; -#endif - /* * IP protocol blocks we attach to sockets. * socket layer -> transport layer interface @@ -513,6 +529,10 @@ struct inet_options { struct proto { + /* These must be first. */ + struct sock *sklist_next; + struct sock *sklist_prev; + void (*close)(struct sock *sk, unsigned long timeout); int (*connect)(struct sock *sk, @@ -524,11 +544,10 @@ struct proto void (*write_wakeup)(struct sock *sk); void (*read_wakeup)(struct sock *sk); - int (*select)(struct sock *sk, int which, - select_table *wait); + unsigned int (*poll)(struct socket *sock, poll_table *wait); int (*ioctl)(struct sock *sk, int cmd, - unsigned long arg); + unsigned long arg); int (*init)(struct sock *sk); int (*destroy)(struct sock *sk); void (*shutdown)(struct sock *sk, int how); @@ -538,7 +557,7 @@ struct proto int optname, char *optval, int *option); int (*sendmsg)(struct sock *sk, struct msghdr *msg, - int len, int noblock, int flags); + int len); int (*recvmsg)(struct sock *sk, struct msghdr *msg, int len, int noblock, int flags, int *addr_len); @@ -548,11 +567,17 @@ struct proto int (*backlog_rcv) (struct sock *sk, struct sk_buff *skb); + /* Keeping track of sk's, looking them up, and port selection methods. */ + void (*hash)(struct sock *sk); + void (*unhash)(struct sock *sk); + void (*rehash)(struct sock *sk); + unsigned short (*good_socknum)(void); + int (*verify_bind)(struct sock *sk, unsigned short snum); + unsigned short max_header; unsigned long retransmits; char name[32]; int inuse, highestinuse; - struct sock ** sock_array; }; #define TIME_WRITE 1 /* Not yet used */ @@ -580,6 +605,46 @@ struct proto #define RCV_SHUTDOWN 1 #define SEND_SHUTDOWN 2 +/* Per-protocol hash table implementations use this to make sure + * nothing changes. + */ +#define SOCKHASH_LOCK() start_bh_atomic() +#define SOCKHASH_UNLOCK() end_bh_atomic() + +/* Some things in the kernel just want to get at a protocols + * entire socket list commensurate, thus... + */ +static __inline__ void add_to_prot_sklist(struct sock *sk) +{ + SOCKHASH_LOCK(); + if(!sk->sklist_next) { + struct proto *p = sk->prot; + + sk->sklist_prev = (struct sock *) p; + sk->sklist_next = p->sklist_next; + p->sklist_next->sklist_prev = sk; + p->sklist_next = sk; + + /* Charge the protocol. */ + sk->prot->inuse += 1; + if(sk->prot->highestinuse < sk->prot->inuse) + sk->prot->highestinuse = sk->prot->inuse; + } + SOCKHASH_UNLOCK(); +} + +static __inline__ void del_from_prot_sklist(struct sock *sk) +{ + SOCKHASH_LOCK(); + if(sk->sklist_next) { + sk->sklist_next->sklist_prev = sk->sklist_prev; + sk->sklist_prev->sklist_next = sk->sklist_next; + sk->sklist_next = NULL; + sk->prot->inuse--; + } + SOCKHASH_UNLOCK(); +} + /* * Used by processes to "lock" a socket state, so that * interrupts and bottom half handlers won't change it @@ -597,14 +662,27 @@ static inline void lock_sock(struct sock *sk) #if 0 /* debugging code: the test isn't even 100% correct, but it can catch bugs */ /* Note that a double lock is ok in theory - it's just _usually_ a bug */ - if (sk->users) { + if (sk->sock_readers) { __label__ here; printk("double lock on socket at %p\n", &&here); here: } #endif - sk->users++; +#ifdef __SMP__ + /* + * This is a very broken bottom half synchronization mechanism. + * You don't want to know.. + */ + { unsigned long flags; + save_flags(flags); + cli(); + sk->sock_readers++; + restore_flags(flags); + } +#else + sk->sock_readers++; barrier(); +#endif } static inline void release_sock(struct sock *sk) @@ -612,14 +690,14 @@ static inline void release_sock(struct sock *sk) barrier(); #if 0 /* debugging code: remove me when ok */ - if (sk->users == 0) { + if (sk->sock_readers == 0) { __label__ here; - sk->users = 1; + sk->sock_readers = 1; printk("trying to unlock unlocked socket at %p\n", &&here); here: } #endif - if ((sk->users = sk->users-1) == 0) + if ((sk->sock_readers = sk->sock_readers-1) == 0) __release_sock(sk); } @@ -646,18 +724,6 @@ static __inline__ int max(unsigned int a, unsigned int b) extern struct sock * sk_alloc(int priority); extern void sk_free(struct sock *sk); extern void destroy_sock(struct sock *sk); -extern unsigned short get_new_socknum(struct proto *, - unsigned short); -extern void inet_put_sock(unsigned short, struct sock *); -extern struct sock *get_sock(struct proto *, unsigned short, - unsigned long, unsigned short, - unsigned long, - unsigned long, unsigned short); -extern struct sock *get_sock_mcast(struct sock *, unsigned short, - unsigned long, unsigned short, - unsigned long); -extern struct sock *get_sock_raw(struct sock *, unsigned short, - unsigned long, unsigned long); extern struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, @@ -665,26 +731,45 @@ extern struct sk_buff *sock_wmalloc(struct sock *sk, extern struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority); -extern void sock_wfree(struct sock *sk, - struct sk_buff *skb); -extern void sock_rfree(struct sock *sk, - struct sk_buff *skb); +extern void sock_wfree(struct sk_buff *skb); +extern void sock_rfree(struct sk_buff *skb); extern unsigned long sock_rspace(struct sock *sk); extern unsigned long sock_wspace(struct sock *sk); -extern int sock_setsockopt(struct sock *sk, int level, +extern int sock_setsockopt(struct socket *sock, int level, int op, char *optval, int optlen); -extern int sock_getsockopt(struct sock *sk, int level, +extern int sock_getsockopt(struct socket *sock, int level, int op, char *optval, int *optlen); -extern struct sk_buff *sock_alloc_send_skb(struct sock *skb, +extern struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, unsigned long fallback, int noblock, int *errcode); +extern int sock_no_fcntl(struct socket *, unsigned int, unsigned long); +extern int sock_no_getsockopt(struct socket *, int , int, + char *, int *); +extern int sock_no_setsockopt(struct socket *, int, int, + char *, int); +extern int sock_no_listen(struct socket *, int); +/* + * Default socket callbacks and setup code + */ + +extern void sock_def_callback1(struct sock *); +extern void sock_def_callback2(struct sock *, int); +extern void sock_def_callback3(struct sock *); + +/* Initialise core socket variables */ +extern void sock_init_data(struct socket *sock, struct sock *sk); + +extern void sklist_remove_socket(struct sock **list, struct sock *sk); +extern void sklist_insert_socket(struct sock **list, struct sock *sk); +extern void sklist_destroy_socket(struct sock **list, struct sock *sk); + /* * Queue a received datagram if it will fit. Stream and sequenced * protocols can't normally use this as they need to fit buffers in @@ -694,12 +779,26 @@ extern struct sk_buff *sock_alloc_send_skb(struct sock *skb, * packet ever received. */ +extern __inline__ void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) +{ + skb->sk = sk; + skb->destructor = sock_wfree; + atomic_add(skb->truesize, &sk->wmem_alloc); +} + +extern __inline__ void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) +{ + skb->sk = sk; + skb->destructor = sock_rfree; + atomic_add(skb->truesize, &sk->rmem_alloc); +} + + extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { - if (sk->rmem_alloc + skb->truesize >= sk->rcvbuf) + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= sk->rcvbuf) return -ENOMEM; - atomic_add(skb->truesize, &sk->rmem_alloc); - skb->sk=sk; + skb_set_owner_r(skb, sk); skb_queue_tail(&sk->receive_queue,skb); if (!sk->dead) sk->data_ready(sk,skb->len); @@ -708,16 +807,26 @@ extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) extern __inline__ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { - if (sk->rmem_alloc + skb->truesize >= sk->rcvbuf) + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= sk->rcvbuf) return -ENOMEM; - atomic_add(skb->truesize, &sk->rmem_alloc); - skb->sk=sk; + skb_set_owner_r(skb, sk); __skb_queue_tail(&sk->receive_queue,skb); if (!sk->dead) sk->data_ready(sk,skb->len); return 0; } +extern __inline__ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) +{ + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= sk->rcvbuf) + return -ENOMEM; + skb_set_owner_r(skb, sk); + __skb_queue_tail(&sk->error_queue,skb); + if (!sk->dead) + sk->data_ready(sk,skb->len); + return 0; +} + /* * Recover an error report and clear atomically */ @@ -728,6 +837,7 @@ extern __inline__ int sock_error(struct sock *sk) return -err; } + /* * Declarations from timer.c */ @@ -743,6 +853,10 @@ extern void net_timer (unsigned long); * Enable debug/info messages */ +#if 0 #define NETDEBUG(x) do { } while (0) +#else +#define NETDEBUG(x) do { x; } while (0) +#endif #endif /* _SOCK_H */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 23fd54501..3822b461f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -20,8 +20,73 @@ #include <linux/config.h> #include <linux/tcp.h> +#include <linux/slab.h> #include <net/checksum.h> +/* This is for all connections with a full identity, no wildcards. + * New scheme, half the table is for TIME_WAIT, the other half is + * for the rest. I'll experiment with dynamic table growth later. + */ +#define TCP_HTABLE_SIZE 1024 + +/* This is for listening sockets, thus all sockets which possess wildcards. */ +#define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ + +/* This is for all sockets, to keep track of the local port allocations. */ +#define TCP_BHTABLE_SIZE 64 + +/* tcp_ipv4.c: These need to be shared by v4 and v6 because the lookup + * and hashing code needs to work with different AF's yet + * the port space is shared. + */ +extern struct sock *tcp_established_hash[TCP_HTABLE_SIZE]; +extern struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE]; +extern struct sock *tcp_bound_hash[TCP_BHTABLE_SIZE]; + +/* These are AF independant. */ +static __inline__ int tcp_bhashfn(__u16 lport) +{ + return (lport ^ (lport >> 7)) & (TCP_BHTABLE_SIZE - 1); +} + +static __inline__ int tcp_sk_bhashfn(struct sock *sk) +{ + __u16 lport = sk->num; + return tcp_bhashfn(lport); +} + +/* These can have wildcards, don't try too hard. */ +static __inline__ int tcp_lhashfn(unsigned short num) +{ + return num & (TCP_LHTABLE_SIZE - 1); +} + +static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) +{ + return tcp_lhashfn(sk->num); +} + +/* Only those holding the sockhash lock call these two things here. + * Note the slightly gross overloading of sk->prev, AF_UNIX is the + * only other main benefactor of that member of SK, so who cares. + */ +static __inline__ void tcp_sk_bindify(struct sock *sk) +{ + int hashent = tcp_sk_bhashfn(sk); + struct sock **htable = &tcp_bound_hash[hashent]; + + if((sk->bind_next = *htable) != NULL) + (*htable)->bind_pprev = &sk->bind_next; + *htable = sk; + sk->bind_pprev = htable; +} + +static __inline__ void tcp_sk_unbindify(struct sock *sk) +{ + if(sk->bind_next) + sk->bind_next->bind_pprev = sk->bind_pprev; + *(sk->bind_pprev) = sk->bind_next; +} #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #define NETHDR_SIZE sizeof(struct ipv6hdr) @@ -31,11 +96,13 @@ /* * 40 is maximal IP options size - * 4 is TCP option size (MSS) + * 20 is the maximum TCP options size we can currently construct on a SYN. + * 40 is the maximum possible TCP options size. */ -#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 4 + MAX_HEADER + 15) +#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 20 + MAX_HEADER + 15) #define MAX_FIN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) +#define BASE_ACK_SIZE (NETHDR_SIZE + MAX_HEADER + 15) #define MAX_ACK_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) #define MAX_RESET_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) @@ -80,9 +147,9 @@ #define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when * I've got something to write and * there is no window */ -#define TCP_KEEPALIVE_TIME (180*60*HZ) /* two hours */ -#define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ -#define TCP_KEEPALIVE_PERIOD (75*HZ) /* period of keepalive check */ +#define TCP_KEEPALIVE_TIME (180*60*HZ) /* two hours */ +#define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ +#define TCP_KEEPALIVE_PERIOD ((75*HZ)>>2) /* period of keepalive check */ #define TCP_NO_CHECK 0 /* turn to one if you want the default * to be no checksum */ @@ -99,6 +166,8 @@ * We don't use these yet, but they are for PAWS and big windows */ #define TCPOPT_WINDOW 3 /* Window scaling */ +#define TCPOPT_SACK_PERM 4 /* SACK Permitted */ +#define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ /* @@ -107,8 +176,15 @@ #define TCPOLEN_MSS 4 #define TCPOLEN_WINDOW 3 +#define TCPOLEN_SACK_PERM 2 #define TCPOLEN_TIMESTAMP 10 +/* + * TCP option flags for parsed options. + */ + +#define TCPOPTF_SACK_PERM 1 +#define TCPOPTF_TIMESTAMP 2 /* * TCP Vegas constants @@ -125,29 +201,14 @@ struct or_calltable { void (*destructor) (struct open_request *req); }; -struct open_request { - struct open_request *dl_next; - struct open_request *dl_prev; - __u32 rcv_isn; - __u32 snt_isn; - __u16 mss; - __u16 rmt_port; - unsigned long expires; - int retrans; - struct or_calltable *class; - struct sock *sk; -}; - struct tcp_v4_open_req { - struct open_request req; __u32 loc_addr; __u32 rmt_addr; - struct options *opt; + struct ip_options *opt; }; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) struct tcp_v6_open_req { - struct open_request req; struct in6_addr loc_addr; struct in6_addr rmt_addr; struct ipv6_options *opt; @@ -155,6 +216,35 @@ struct tcp_v6_open_req { }; #endif +struct open_request { + struct open_request *dl_next; + struct open_request **dl_pprev; + __u32 rcv_isn; + __u32 snt_isn; + __u16 rmt_port; + __u16 mss; + __u8 snd_wscale; + char sack_ok; + char tstamp_ok; + __u32 ts_recent; + unsigned long expires; + int retrans; + struct or_calltable *class; + struct sock *sk; + union { + struct tcp_v4_open_req v4_req; +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + struct tcp_v6_open_req v6_req; +#endif + } af; +}; + +/* SLAB cache for open requests. */ +extern kmem_cache_t *tcp_openreq_cachep; + +#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC) +#define tcp_openreq_free(req) kmem_cache_free(tcp_openreq_cachep, req) + /* * Pointers to address related TCP functions * (i.e. things that depend on the address family) @@ -164,10 +254,7 @@ struct tcp_func { int (*build_net_header) (struct sock *sk, struct sk_buff *skb); - void (*queue_xmit) (struct sock *sk, - struct device *dev, - struct sk_buff *skb, - int free); + void (*queue_xmit) (struct sk_buff *skb); void (*send_check) (struct sock *sk, struct tcphdr *th, @@ -208,6 +295,8 @@ struct tcp_func { void (*addr2sockaddr) (struct sock *sk, struct sockaddr *); + void (*send_reset) (struct sk_buff *skb); + int sockaddr_len; }; @@ -237,24 +326,18 @@ extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3) extern struct proto tcp_prot; extern struct tcp_mib tcp_statistics; -extern void tcp_v4_err(int type, int code, - unsigned char *header, __u32 info, - __u32 daddr, __u32 saddr, - struct inet_protocol *protocol, - int len); +extern unsigned short tcp_good_socknum(void); + +extern void tcp_v4_err(struct sk_buff *skb, + unsigned char *); extern void tcp_shutdown (struct sock *sk, int how); -extern int tcp_v4_rcv(struct sk_buff *skb, - struct device *dev, - struct options *opt, __u32 daddr, - unsigned short len, __u32 saddr, - int redo, - struct inet_protocol *protocol); +extern int tcp_v4_rcv(struct sk_buff *skb, + unsigned short len); extern int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, - int len, int nonblock, int flags); extern int tcp_ioctl(struct sock *sk, @@ -266,7 +349,7 @@ extern int tcp_rcv_state_process(struct sock *sk, struct tcphdr *th, void *opt, __u16 len); -extern void tcp_rcv_established(struct sock *sk, +extern int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, struct tcphdr *th, __u16 len); @@ -274,8 +357,7 @@ extern void tcp_rcv_established(struct sock *sk, extern void tcp_close(struct sock *sk, unsigned long timeout); extern struct sock * tcp_accept(struct sock *sk, int flags); -extern int tcp_select(struct sock *sk, int sel_type, - select_table *wait); +extern unsigned int tcp_poll(struct socket *sock, poll_table *wait); extern int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen); @@ -288,7 +370,7 @@ extern int tcp_recvmsg(struct sock *sk, int len, int nonblock, int flags, int *addr_len); -extern int tcp_parse_options(struct tcphdr *th); +extern void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp); /* * TCP v4 functions exported for the inet6 API @@ -312,8 +394,9 @@ extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, struct open_request *req); -extern int tcp_v4_backlog_rcv(struct sock *sk, - struct sk_buff *skb); +extern int tcp_v4_do_rcv(struct sock *sk, + struct sk_buff *skb); + extern int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); @@ -335,9 +418,6 @@ extern int tcp_send_skb(struct sock *, struct sk_buff *); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk, int max_timeout); -/* tcp_input.c */ -extern void tcp_cache_zap(void); - /* CONFIG_IP_TRANSPARENT_PROXY */ extern int tcp_chkaddr(struct sk_buff *); @@ -442,66 +522,84 @@ static __inline__ void tcp_set_state(struct sock *sk, int state) sk->state = state; #ifdef STATE_TRACE - if(sk->debug) - printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]); + SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]); #endif switch (state) { case TCP_ESTABLISHED: - if (oldstate != TCP_ESTABLISHED) { + if (oldstate != TCP_ESTABLISHED) tcp_statistics.TcpCurrEstab++; - } break; case TCP_CLOSE: - tcp_cache_zap(); /* Should be about 2 rtt's */ net_reset_timer(sk, TIME_DONE, min(tp->srtt * 2, TCP_DONE_TIME)); /* fall through */ default: if (oldstate==TCP_ESTABLISHED) tcp_statistics.TcpCurrEstab--; + if (state == TCP_TIME_WAIT) + sk->prot->rehash(sk); } } -extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req) +/* + * Construct a tcp options header for a SYN or SYN_ACK packet. + * If this is every changed make sure to change the definition of + * MAX_SYN_SIZE to match the new maximum number of options that you + * can generate. + * FIXME: This is completely disgusting. + * This is probably a good candidate for a bit of assembly magic. + * It would be especially magical to compute the checksum for this + * stuff on the fly here. + */ +extern __inline__ int tcp_syn_build_options(struct sk_buff *skb, int mss, int sack, int ts, int wscale) { - if (req->dl_next == req) - { - tp->syn_wait_queue = NULL; - } - else - { - req->dl_prev->dl_next = req->dl_next; - req->dl_next->dl_prev = req->dl_prev; - - if (tp->syn_wait_queue == req) - { - tp->syn_wait_queue = req->dl_next; + int count = 4 + (wscale ? 4 : 0) + ((ts || sack) ? 4 : 0) + (ts ? 8 : 0); + unsigned char *optr = skb_put(skb,count); + __u32 *ptr = (__u32 *)optr; + + /* + * We always get an MSS option. + */ + *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); + if (ts) { + if (sack) { + *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(jiffies); /* TSVAL */ + *ptr++ = htonl(0); /* TSECR */ + } else { + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); + *ptr++ = htonl(jiffies); /* TSVAL */ + *ptr++ = htonl(0); /* TSECR */ } + } else if (sack) { + *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) + | (TCPOPT_NOP << 8) | TCPOPT_NOP); } - - req->dl_prev = req->dl_next = NULL; + if (wscale) + *ptr++ = htonl((TCPOPT_WINDOW << 24) | (TCPOLEN_WINDOW << 16) | wscale); + skb->csum = csum_partial(optr, count, 0); + return count; } -extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) +extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req) { - if (!tp->syn_wait_queue) - { - req->dl_next = req; - req->dl_prev = req; - tp->syn_wait_queue = req; - } + if(req->dl_next) + req->dl_next->dl_pprev = req->dl_pprev; else - { - struct open_request *list = tp->syn_wait_queue; - - req->dl_next = list; - req->dl_prev = list->dl_prev; - list->dl_prev->dl_next = req; - list->dl_prev = req; - } + tp->syn_wait_last = req->dl_pprev; + *req->dl_pprev = req->dl_next; +} +extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) +{ + req->dl_next = NULL; + req->dl_pprev = tp->syn_wait_last; + *tp->syn_wait_last = req; + tp->syn_wait_last = &req->dl_next; } extern void __tcp_inc_slow_timer(struct tcp_sl_timer *slt); @@ -509,7 +607,7 @@ extern __inline__ void tcp_inc_slow_timer(int timer) { struct tcp_sl_timer *slt = &tcp_slt_array[timer]; - if (slt->count == 0) + if (atomic_read(&slt->count) == 0) { __tcp_inc_slow_timer(slt); } @@ -525,4 +623,3 @@ extern __inline__ void tcp_dec_slow_timer(int timer) } #endif /* _TCP_H */ - diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index 412943e4d..23ed805a0 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h @@ -28,7 +28,8 @@ extern int datagram_recv_ctl(struct sock *sk, extern int datagram_send_ctl(struct msghdr *msg, struct device **src_dev, struct in6_addr **src_addr, - struct ipv6_options *opt); + struct ipv6_options *opt, + int *hlimit); #define LOOPBACK4_IPV6 __constant_htonl(0x7f000006) diff --git a/include/net/udp.h b/include/net/udp.h index d834feb6d..0fa99fb1c 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -24,6 +24,15 @@ #include <linux/udp.h> +#define UDP_HTABLE_SIZE 128 + +/* udp.c: This needs to be shared by v4 and v6 because the lookup + * and hashing code needs to work with different AF's yet + * the port space is shared. + */ +extern struct sock *udp_hash[UDP_HTABLE_SIZE]; + +extern unsigned short udp_good_socknum(void); #define UDP_NO_CHECK 0 @@ -31,23 +40,14 @@ extern struct proto udp_prot; -extern void udp_err(int type, int code, unsigned char *header, - __u32 info, __u32 daddr, __u32 saddr, - struct inet_protocol *protocol, int len); -extern void udp_send_check(struct udphdr *uh, __u32 saddr, - __u32 daddr, int len, struct sock *sk); +extern void udp_err(struct sk_buff *, unsigned char *); extern int udp_connect(struct sock *sk, struct sockaddr *usin, int addr_len); -extern int udp_sendmsg(struct sock *sk, struct msghdr *msg, - int len, int noblock, int flags); +extern int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len); -extern int udp_rcv(struct sk_buff *skb, struct device *dev, - struct options *opt, __u32 daddr, - unsigned short len, __u32 saddr, int redo, - struct inet_protocol *protocol); +extern int udp_rcv(struct sk_buff *skb, unsigned short len); extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); -extern void udp_cache_zap(void); /* Remove udp last socket cache */ /* CONFIG_IP_TRANSPARENT_PROXY */ extern int udp_chkaddr(struct sk_buff *skb); diff --git a/include/net/x25.h b/include/net/x25.h new file mode 100644 index 000000000..c98afb6de --- /dev/null +++ b/include/net/x25.h @@ -0,0 +1,208 @@ +/* + * Declarations of X.25 Packet Layer type objects. + * + * Jonathan Naylor 17/11/96 + */ + +#ifndef _X25_H +#define _X25_H +#include <linux/x25.h> + +#define X25_SLOWHZ 1 /* Run timing at 1 Hz */ + +#define X25_ADDR_LEN 16 + +#define X25_MAX_L2_LEN 18 /* 802.2 LLC */ + +#define X25_STD_MIN_LEN 3 +#define X25_EXT_MIN_LEN 4 + +#define X25_GFI_SEQ_MASK 0x30 +#define X25_GFI_STDSEQ 0x10 +#define X25_GFI_EXTSEQ 0x20 + +#define X25_Q_BIT 0x80 +#define X25_D_BIT 0x40 +#define X25_STD_M_BIT 0x10 +#define X25_EXT_M_BIT 0x01 + +#define X25_CALL_REQUEST 0x0B +#define X25_CALL_ACCEPTED 0x0F +#define X25_CLEAR_REQUEST 0x13 +#define X25_CLEAR_CONFIRMATION 0x17 +#define X25_DATA 0x00 +#define X25_INTERRUPT 0x23 +#define X25_INTERRUPT_CONFIRMATION 0x27 +#define X25_RR 0x01 +#define X25_RNR 0x05 +#define X25_REJ 0x09 +#define X25_RESET_REQUEST 0x1B +#define X25_RESET_CONFIRMATION 0x1F +#define X25_REGISTRATION_REQUEST 0xF3 +#define X25_REGISTRATION_CONFIRMATION 0xF7 +#define X25_RESTART_REQUEST 0xFB +#define X25_RESTART_CONFIRMATION 0xFF +#define X25_DIAGNOSTIC 0xF1 +#define X25_ILLEGAL 0xFD + +/* Define the various conditions that may exist */ + +#define X25_COND_ACK_PENDING 0x01 +#define X25_COND_OWN_RX_BUSY 0x02 +#define X25_COND_PEER_RX_BUSY 0x04 + +/* Define Link State constants. */ +enum { + X25_STATE_0, /* Ready */ + X25_STATE_1, /* Awaiting Call Accepted */ + X25_STATE_2, /* Awaiting Clear Confirmation */ + X25_STATE_3, /* Data Transfer */ + X25_STATE_4 /* Awaiting Reset Confirmation */ +}; + +enum { + X25_LINK_STATE_0, + X25_LINK_STATE_1, + X25_LINK_STATE_2, + X25_LINK_STATE_3 +}; + +#define X25_DEFAULT_T20 (180 * X25_SLOWHZ) /* Default T20 value */ +#define X25_DEFAULT_T21 (200 * X25_SLOWHZ) /* Default T21 value */ +#define X25_DEFAULT_T22 (180 * X25_SLOWHZ) /* Default T22 value */ +#define X25_DEFAULT_T23 (180 * X25_SLOWHZ) /* Default T23 value */ +#define X25_DEFAULT_T2 (3 * X25_SLOWHZ) /* Default ack holdback value */ + +#define X25_DEFAULT_WINDOW_SIZE 2 /* Default Window Size */ +#define X25_DEFAULT_PACKET_SIZE X25_PS128 /* Default Packet Size */ +#define X25_DEFAULT_THROUGHPUT 0x0A /* Deafult Throughput */ +#define X25_DEFAULT_REVERSE 0x00 /* Default Reverse Charging */ + +#define X25_SMODULUS 8 +#define X25_EMODULUS 128 + +/* + * X.25 Facilities constants. + */ + +#define X25_FAC_CLASS_MASK 0xC0 + +#define X25_FAC_CLASS_A 0x00 +#define X25_FAC_CLASS_B 0x40 +#define X25_FAC_CLASS_C 0x80 +#define X25_FAC_CLASS_D 0xC0 + +#define X25_FAC_REVERSE 0x01 +#define X25_FAC_THROUGHPUT 0x02 +#define X25_FAC_PACKET_SIZE 0x42 +#define X25_FAC_WINDOW_SIZE 0x43 + +#define X25_MAX_FAC_LEN 20 /* Plenty to spare */ +#define X25_MAX_CUD_LEN 128 + +struct x25_route { + struct x25_route *next; + x25_address address; /* Start of address range */ + unsigned int sigdigits; /* Number of sig digits */ + struct device *dev; /* More than one for MLP */ +}; + +struct x25_neigh { + struct x25_neigh *next; + struct device *dev; + unsigned int state; + unsigned int extended; + struct sk_buff_head queue; + unsigned short t20, t20timer; + struct timer_list timer; +}; + +typedef struct { + x25_address source_addr, dest_addr; + struct x25_neigh *neighbour; + unsigned int lci; + unsigned char state, condition, qbitincl, intflag; + unsigned short vs, vr, va, vl; + unsigned short timer; + unsigned short t2, t21, t22, t23; + unsigned short fraglen; + struct sk_buff_head fragment_queue; + struct sk_buff_head interrupt_in_queue; + struct sk_buff_head interrupt_out_queue; + struct sock *sk; /* Backlink to socket */ + struct x25_facilities facilities; + struct x25_calluserdata calluserdata; +} x25_cb; + +/* af_x25.c */ +extern int sysctl_x25_restart_request_timeout; +extern int sysctl_x25_call_request_timeout; +extern int sysctl_x25_reset_request_timeout; +extern int sysctl_x25_clear_request_timeout; +extern int sysctl_x25_ack_holdback_timeout; + +extern int x25_addr_ntoa(unsigned char *, x25_address *, x25_address *); +extern int x25_addr_aton(unsigned char *, x25_address *, x25_address *); +extern unsigned int x25_new_lci(void); +extern struct sock *x25_find_socket(unsigned int); +extern void x25_destroy_socket(struct sock *); +extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int); + +#include <net/x25call.h> + +/* x25_dev.c */ +extern void x25_send_frame(struct sk_buff *, struct x25_neigh *); +extern int x25_lapb_receive_frame(struct sk_buff *, struct device *, struct packet_type *); +extern int x25_llc_receive_frame(struct sk_buff *, struct device *, struct packet_type *); +extern void x25_establish_link(struct x25_neigh *); +extern void x25_terminate_link(struct x25_neigh *); + +/* x25_in.c */ +extern int x25_process_rx_frame(struct sock *, struct sk_buff *); + +/* x25_link.c */ +extern void x25_link_control(struct sk_buff *, struct x25_neigh *, unsigned short); +extern void x25_link_device_up(struct device *); +extern void x25_link_device_down(struct device *); +extern void x25_link_established(struct x25_neigh *); +extern void x25_link_terminated(struct x25_neigh *); +extern void x25_transmit_restart_request(struct x25_neigh *); +extern void x25_transmit_restart_confirmation(struct x25_neigh *); +extern void x25_transmit_diagnostic(struct x25_neigh *, unsigned char); +extern void x25_transmit_clear_request(struct x25_neigh *, unsigned int, unsigned char); +extern void x25_transmit_link(struct sk_buff *, struct x25_neigh *); +extern int x25_subscr_ioctl(unsigned int, void *); +extern struct x25_neigh *x25_get_neigh(struct device *); +extern int x25_link_get_info(char *, char **, off_t, int, int); +extern void x25_link_free(void); + +/* x25_out.c */ +extern void x25_output(struct sock *, struct sk_buff *); +extern void x25_kick(struct sock *); +extern void x25_enquiry_response(struct sock *); +extern void x25_check_iframes_acked(struct sock *, unsigned short); + +/* x25_route.c */ +extern struct device *x25_get_route(x25_address *); +extern struct device *x25_dev_get(char *); +extern void x25_route_device_down(struct device *); +extern int x25_route_ioctl(unsigned int, void *); +extern int x25_routes_get_info(char *, char **, off_t, int, int); +extern void x25_route_free(void); + +/* x25_subr.c */ +extern void x25_clear_queues(struct sock *); +extern int x25_validate_nr(struct sock *, unsigned short); +extern void x25_write_internal(struct sock *, int); +extern int x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int *, int *); +extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *); +extern int x25_create_facilities(unsigned char *, struct x25_facilities *); + +/* x25_timer.c */ +extern void x25_set_timer(struct sock *); + +/* sysctl_net_x25.c */ +extern void x25_register_sysctl(void); +extern void x25_unregister_sysctl(void); + +#endif |