diff --git a/[refs] b/[refs] index 2a694b7fc3f5..c2bc959bd87e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bf603625660b1742004bf86432ce3c210d14d4fd +refs/heads/master: 81b999b10b3246fd80691a7936a564deb99640b9 diff --git a/trunk/arch/sparc/lib/copy_user.S b/trunk/arch/sparc/lib/copy_user.S index ef095b6c43b1..577505b692ae 100644 --- a/trunk/arch/sparc/lib/copy_user.S +++ b/trunk/arch/sparc/lib/copy_user.S @@ -14,7 +14,6 @@ #include #include #include -#include /* Work around cpp -rob */ #define ALLOC #alloc @@ -367,9 +366,6 @@ fixupretl: blu 1f cmp %o1, %g1 bgeu 1f - ld [%g6 + TI_PREEMPT], %g1 - cmp %g1, 0 - bne 1f nop save %sp, -64, %sp mov %i0, %o0 diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 647610ecb580..4844b543bed0 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,11 +1,12 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git5 -# Tue Sep 26 09:30:47 2006 +# Linux kernel version: 2.6.18-git7 +# Wed Sep 27 21:53:10 2006 # CONFIG_X86_64=y CONFIG_64BIT=y CONFIG_X86=y +CONFIG_ZONE_DMA32=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -179,6 +180,7 @@ CONFIG_GENERIC_PENDING_IRQ=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_SOFTWARE_SUSPEND=y CONFIG_PM_STD_PARTITION="" CONFIG_SUSPEND_SMP=y @@ -251,6 +253,7 @@ CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCIEPORTBUS=y CONFIG_PCI_MSI=y +# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -1458,6 +1461,7 @@ CONFIG_KPROBES=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_KERNEL=y diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 6b4edb63c4c4..7fcf015021ec 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4.45" -#define DRV_MODULE_RELDATE "September 29, 2006" +#define DRV_MODULE_VERSION "1.4.44" +#define DRV_MODULE_RELDATE "August 10, 2006" #define RUN_AT(x) (jiffies + (x)) @@ -5805,34 +5805,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->cmd_ticks_int = bp->cmd_ticks; } - /* Disable MSI on 5706 if AMD 8132 bridge is found. - * - * MSI is defined to be 32-bit write. The 5706 does 64-bit MSI writes - * with byte enables disabled on the unused 32-bit word. This is legal - * but causes problems on the AMD 8132 which will eventually stop - * responding after a while. - * - * AMD believes this incompatibility is unique to the 5706, and - * prefers to locally disable MSI rather than globally disabling it - * using pci_msi_quirk. - */ - if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) { - struct pci_dev *amd_8132 = NULL; - - while ((amd_8132 = pci_get_device(PCI_VENDOR_ID_AMD, - PCI_DEVICE_ID_AMD_8132_BRIDGE, - amd_8132))) { - u8 rev; - - pci_read_config_byte(amd_8132, PCI_REVISION_ID, &rev); - if (rev >= 0x10 && rev <= 0x13) { - disable_msi = 1; - pci_dev_put(amd_8132); - break; - } - } - } - bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL; bp->req_line_speed = 0; if (bp->phy_flags & PHY_SERDES_FLAG) { diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index 0da3ebfff82d..d34f336d53d8 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/drivers/serial/sunzilog.c @@ -1270,7 +1270,7 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up) } #endif -static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) +static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) { struct zilog_channel __iomem *channel; unsigned long flags; diff --git a/trunk/include/linux/atmlec.h b/trunk/include/linux/atmlec.h index 6f5a1bab8f50..f267f2442766 100644 --- a/trunk/include/linux/atmlec.h +++ b/trunk/include/linux/atmlec.h @@ -1,7 +1,9 @@ /* - * ATM Lan Emulation Daemon driver interface + * + * ATM Lan Emulation Daemon vs. driver interface + * + * mkiiskila@yahoo.com * - * Marko Kiiskila */ #ifndef _ATMLEC_H_ @@ -11,87 +13,76 @@ #include #include #include - /* ATM lec daemon control socket */ -#define ATMLEC_CTRL _IO('a', ATMIOC_LANE) -#define ATMLEC_DATA _IO('a', ATMIOC_LANE+1) -#define ATMLEC_MCAST _IO('a', ATMIOC_LANE+2) +#define ATMLEC_CTRL _IO('a',ATMIOC_LANE) +#define ATMLEC_DATA _IO('a',ATMIOC_LANE+1) +#define ATMLEC_MCAST _IO('a',ATMIOC_LANE+2) /* Maximum number of LEC interfaces (tweakable) */ #define MAX_LEC_ITF 48 -/* - * From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring. +/* From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring. * E.g. if MAX_LEC_ITF = 48 and NUM_TR_DEVS = 8, then lec0-lec39 are for * Ethernet ELANs and lec40-lec47 are for Token Ring ELANS. */ #define NUM_TR_DEVS 8 -typedef enum { - l_set_mac_addr, - l_del_mac_addr, - l_svc_setup, - l_addr_delete, - l_topology_change, - l_flush_complete, - l_arp_update, - l_narp_req, /* LANE2 mandates the use of this */ - l_config, - l_flush_tran_id, - l_set_lecid, - l_arp_xmt, - l_rdesc_arp_xmt, - l_associate_req, - l_should_bridge /* should we bridge this MAC? */ +typedef enum { + l_set_mac_addr, l_del_mac_addr, + l_svc_setup, + l_addr_delete, l_topology_change, + l_flush_complete, l_arp_update, + l_narp_req, /* LANE2 mandates the use of this */ + l_config, l_flush_tran_id, + l_set_lecid, l_arp_xmt, + l_rdesc_arp_xmt, + l_associate_req, + l_should_bridge /* should we bridge this MAC? */ } atmlec_msg_type; #define ATMLEC_MSG_TYPE_MAX l_should_bridge struct atmlec_config_msg { - unsigned int maximum_unknown_frame_count; - unsigned int max_unknown_frame_time; - unsigned short max_retry_count; - unsigned int aging_time; - unsigned int forward_delay_time; - unsigned int arp_response_time; - unsigned int flush_timeout; - unsigned int path_switching_delay; - unsigned int lane_version; /* LANE2: 1 for LANEv1, 2 for LANEv2 */ - int mtu; - int is_proxy; + unsigned int maximum_unknown_frame_count; + unsigned int max_unknown_frame_time; + unsigned short max_retry_count; + unsigned int aging_time; + unsigned int forward_delay_time; + unsigned int arp_response_time; + unsigned int flush_timeout; + unsigned int path_switching_delay; + unsigned int lane_version; /* LANE2: 1 for LANEv1, 2 for LANEv2 */ + int mtu; + int is_proxy; }; - + struct atmlec_msg { - atmlec_msg_type type; - int sizeoftlvs; /* LANE2: if != 0, tlvs follow */ - union { - struct { - unsigned char mac_addr[ETH_ALEN]; - unsigned char atm_addr[ATM_ESA_LEN]; - unsigned int flag; /* - * Topology_change flag, - * remoteflag, permanent flag, - * lecid, transaction id - */ - unsigned int targetless_le_arp; /* LANE2 */ - unsigned int no_source_le_narp; /* LANE2 */ - } normal; - struct atmlec_config_msg config; - struct { - uint16_t lec_id; /* requestor lec_id */ - uint32_t tran_id; /* transaction id */ - unsigned char mac_addr[ETH_ALEN]; /* dst mac addr */ - unsigned char atm_addr[ATM_ESA_LEN]; /* reqestor ATM addr */ - } proxy; /* - * For mapping LE_ARP requests to responses. Filled by - * zeppelin, returned by kernel. Used only when proxying - */ - } content; + atmlec_msg_type type; + int sizeoftlvs; /* LANE2: if != 0, tlvs follow */ + union { + struct { + unsigned char mac_addr[ETH_ALEN]; + unsigned char atm_addr[ATM_ESA_LEN]; + unsigned int flag;/* Topology_change flag, + remoteflag, permanent flag, + lecid, transaction id */ + unsigned int targetless_le_arp; /* LANE2 */ + unsigned int no_source_le_narp; /* LANE2 */ + } normal; + struct atmlec_config_msg config; + struct { + uint16_t lec_id; /* requestor lec_id */ + uint32_t tran_id; /* transaction id */ + unsigned char mac_addr[ETH_ALEN]; /* dst mac addr */ + unsigned char atm_addr[ATM_ESA_LEN]; /* reqestor ATM addr */ + } proxy; + /* For mapping LE_ARP requests to responses. Filled by */ + } content; /* zeppelin, returned by kernel. Used only when proxying */ } __ATM_API_ALIGN; struct atmlec_ioc { - int dev_num; - unsigned char atm_addr[ATM_ESA_LEN]; - unsigned char receive; /* 1= receive vcc, 0 = send vcc */ + int dev_num; + unsigned char atm_addr[ATM_ESA_LEN]; + unsigned char receive; /* 1= receive vcc, 0 = send vcc */ }; #endif /* _ATMLEC_H_ */ diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index c3aa09751814..42719d07612a 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -95,11 +95,12 @@ #define AUDIT_MAC_POLICY_LOAD 1403 /* Policy file load */ #define AUDIT_MAC_STATUS 1404 /* Changed enforcing,permissive,off */ #define AUDIT_MAC_CONFIG_CHANGE 1405 /* Changes to booleans */ -#define AUDIT_MAC_UNLBL_ALLOW 1406 /* NetLabel: allow unlabeled traffic */ -#define AUDIT_MAC_CIPSOV4_ADD 1407 /* NetLabel: add CIPSOv4 DOI entry */ -#define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */ -#define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */ -#define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */ +#define AUDIT_MAC_UNLBL_ACCEPT 1406 /* NetLabel: allow unlabeled traffic */ +#define AUDIT_MAC_UNLBL_DENY 1407 /* NetLabel: deny unlabeled traffic */ +#define AUDIT_MAC_CIPSOV4_ADD 1408 /* NetLabel: add CIPSOv4 DOI entry */ +#define AUDIT_MAC_CIPSOV4_DEL 1409 /* NetLabel: del CIPSOv4 DOI entry */ +#define AUDIT_MAC_MAP_ADD 1410 /* NetLabel: add LSM domain mapping */ +#define AUDIT_MAC_MAP_DEL 1411 /* NetLabel: del LSM domain mapping */ #define AUDIT_FIRST_KERN_ANOM_MSG 1700 #define AUDIT_LAST_KERN_ANOM_MSG 1799 diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index c9ffbc3843d5..b7e85ff045ea 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -507,7 +507,6 @@ #define PCI_DEVICE_ID_AMD_8151_0 0x7454 #define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 #define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 -#define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458 #define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 #define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 #define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093 diff --git a/trunk/include/net/cipso_ipv4.h b/trunk/include/net/cipso_ipv4.h index 718b4d9c891f..5d6ae1b2b196 100644 --- a/trunk/include/net/cipso_ipv4.h +++ b/trunk/include/net/cipso_ipv4.h @@ -129,7 +129,7 @@ extern int cipso_v4_rbm_strictvalid; #ifdef CONFIG_NETLABEL int cipso_v4_doi_add(struct cipso_v4_doi *doi_def); int cipso_v4_doi_remove(u32 doi, - struct netlbl_audit *audit_info, + u32 audit_secid, void (*callback) (struct rcu_head * head)); struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi); int cipso_v4_doi_walk(u32 *skip_cnt, @@ -145,7 +145,7 @@ static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) } static inline int cipso_v4_doi_remove(u32 doi, - struct netlbl_audit *audit_info, + u32 audit_secid, void (*callback) (struct rcu_head * head)) { return 0; diff --git a/trunk/include/net/netlabel.h b/trunk/include/net/netlabel.h index c63a58058e21..190bfdbbdba6 100644 --- a/trunk/include/net/netlabel.h +++ b/trunk/include/net/netlabel.h @@ -92,17 +92,11 @@ * */ -/* NetLabel audit information */ -struct netlbl_audit { - u32 secid; - uid_t loginuid; -}; - /* Domain mapping definition struct */ struct netlbl_dom_map; /* Domain mapping operations */ -int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); +int netlbl_domhsh_remove(const char *domain, u32 audit_secid); /* LSM security attributes */ struct netlbl_lsm_cache { diff --git a/trunk/net/atm/lec.c b/trunk/net/atm/lec.c index 66c57c1091a8..b4aa489849df 100644 --- a/trunk/net/atm/lec.c +++ b/trunk/net/atm/lec.c @@ -1,7 +1,7 @@ /* * lec.c: Lan Emulation driver + * Marko Kiiskila mkiiskila@yahoo.com * - * Marko Kiiskila */ #include @@ -38,7 +38,7 @@ #include #include "../bridge/br_private.h" -static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 }; +static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00}; #endif /* Modular too */ @@ -55,41 +55,38 @@ static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 }; #define DPRINTK(format,args...) #endif -#define DUMP_PACKETS 0 /* - * 0 = None, - * 1 = 30 first bytes - * 2 = Whole packet - */ +#define DUMP_PACKETS 0 /* 0 = None, + * 1 = 30 first bytes + * 2 = Whole packet + */ -#define LEC_UNRES_QUE_LEN 8 /* - * number of tx packets to queue for a - * single destination while waiting for SVC - */ +#define LEC_UNRES_QUE_LEN 8 /* number of tx packets to queue for a + single destination while waiting for SVC */ static int lec_open(struct net_device *dev); static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev); static int lec_close(struct net_device *dev); static struct net_device_stats *lec_get_stats(struct net_device *dev); static void lec_init(struct net_device *dev); -static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, - unsigned char *mac_addr); +static struct lec_arp_table* lec_arp_find(struct lec_priv *priv, + unsigned char *mac_addr); static int lec_arp_remove(struct lec_priv *priv, - struct lec_arp_table *to_remove); + struct lec_arp_table *to_remove); /* LANE2 functions */ -static void lane2_associate_ind(struct net_device *dev, u8 *mac_address, - u8 *tlvs, u32 sizeoftlvs); +static void lane2_associate_ind (struct net_device *dev, u8 *mac_address, + u8 *tlvs, u32 sizeoftlvs); static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force, - u8 **tlvs, u32 *sizeoftlvs); -static int lane2_associate_req(struct net_device *dev, u8 *lan_dst, - u8 *tlvs, u32 sizeoftlvs); + u8 **tlvs, u32 *sizeoftlvs); +static int lane2_associate_req (struct net_device *dev, u8 *lan_dst, + u8 *tlvs, u32 sizeoftlvs); -static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, +static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, unsigned long permanent); static void lec_arp_check_empties(struct lec_priv *priv, struct atm_vcc *vcc, struct sk_buff *skb); static void lec_arp_destroy(struct lec_priv *priv); static void lec_arp_init(struct lec_priv *priv); -static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, +static struct atm_vcc* lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, int is_rdesc, struct lec_arp_table **ret_entry); @@ -103,30 +100,16 @@ static void lec_set_flush_tran_id(struct lec_priv *priv, unsigned long tran_id); static void lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, struct atm_vcc *vcc, - void (*old_push) (struct atm_vcc *vcc, - struct sk_buff *skb)); + void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb)); static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc); -/* must be done under lec_arp_lock */ -static inline void lec_arp_hold(struct lec_arp_table *entry) -{ - atomic_inc(&entry->usage); -} - -static inline void lec_arp_put(struct lec_arp_table *entry) -{ - if (atomic_dec_and_test(&entry->usage)) - kfree(entry); -} - - static struct lane2_ops lane2_ops = { - lane2_resolve, /* resolve, spec 3.1.3 */ - lane2_associate_req, /* associate_req, spec 3.1.4 */ - NULL /* associate indicator, spec 3.1.5 */ + lane2_resolve, /* resolve, spec 3.1.3 */ + lane2_associate_req, /* associate_req, spec 3.1.4 */ + NULL /* associate indicator, spec 3.1.5 */ }; -static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +static unsigned char bus_mac[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; /* Device structures */ static struct net_device *dev_lec[MAX_LEC_ITF]; @@ -134,39 +117,36 @@ static struct net_device *dev_lec[MAX_LEC_ITF]; #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev) { - struct ethhdr *eth; - char *buff; - struct lec_priv *priv; - - /* - * Check if this is a BPDU. If so, ask zeppelin to send - * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit - * as the Config BPDU has - */ - eth = (struct ethhdr *)skb->data; - buff = skb->data + skb->dev->hard_header_len; - if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) { + struct ethhdr *eth; + char *buff; + struct lec_priv *priv; + + /* Check if this is a BPDU. If so, ask zeppelin to send + * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit + * as the Config BPDU has */ + eth = (struct ethhdr *)skb->data; + buff = skb->data + skb->dev->hard_header_len; + if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) { struct sock *sk; - struct sk_buff *skb2; - struct atmlec_msg *mesg; - - skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC); - if (skb2 == NULL) - return; - skb2->len = sizeof(struct atmlec_msg); - mesg = (struct atmlec_msg *)skb2->data; - mesg->type = l_topology_change; - buff += 4; - mesg->content.normal.flag = *buff & 0x01; /* 0x01 is topology change */ - - priv = (struct lec_priv *)dev->priv; - atm_force_charge(priv->lecd, skb2->truesize); + struct sk_buff *skb2; + struct atmlec_msg *mesg; + + skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC); + if (skb2 == NULL) return; + skb2->len = sizeof(struct atmlec_msg); + mesg = (struct atmlec_msg *)skb2->data; + mesg->type = l_topology_change; + buff += 4; + mesg->content.normal.flag = *buff & 0x01; /* 0x01 is topology change */ + + priv = (struct lec_priv *)dev->priv; + atm_force_charge(priv->lecd, skb2->truesize); sk = sk_atm(priv->lecd); - skb_queue_tail(&sk->sk_receive_queue, skb2); - sk->sk_data_ready(sk, skb2->len); - } + skb_queue_tail(&sk->sk_receive_queue, skb2); + sk->sk_data_ready(sk, skb2->len); + } - return; + return; } #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */ @@ -182,35 +162,36 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev) #ifdef CONFIG_TR static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc) { - struct trh_hdr *trh; - int riflen, num_rdsc; - - trh = (struct trh_hdr *)packet; - if (trh->daddr[0] & (uint8_t) 0x80) - return bus_mac; /* multicast */ - - if (trh->saddr[0] & TR_RII) { - riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8; - if ((ntohs(trh->rcf) >> 13) != 0) - return bus_mac; /* ARE or STE */ - } else - return trh->daddr; /* not source routed */ - - if (riflen < 6) - return trh->daddr; /* last hop, source routed */ - - /* riflen is 6 or more, packet has more than one route descriptor */ - num_rdsc = (riflen / 2) - 1; - memset(rdesc, 0, ETH_ALEN); - /* offset 4 comes from LAN destination field in LE control frames */ - if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT)) - memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(uint16_t)); - else { - memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t)); - rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0)); - } - - return NULL; + struct trh_hdr *trh; + int riflen, num_rdsc; + + trh = (struct trh_hdr *)packet; + if (trh->daddr[0] & (uint8_t)0x80) + return bus_mac; /* multicast */ + + if (trh->saddr[0] & TR_RII) { + riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8; + if ((ntohs(trh->rcf) >> 13) != 0) + return bus_mac; /* ARE or STE */ + } + else + return trh->daddr; /* not source routed */ + + if (riflen < 6) + return trh->daddr; /* last hop, source routed */ + + /* riflen is 6 or more, packet has more than one route descriptor */ + num_rdsc = (riflen/2) - 1; + memset(rdesc, 0, ETH_ALEN); + /* offset 4 comes from LAN destination field in LE control frames */ + if (trh->rcf & htons((uint16_t)TR_RCF_DIR_BIT)) + memcpy(&rdesc[4], &trh->rseg[num_rdsc-2], sizeof(uint16_t)); + else { + memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t)); + rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0)); + } + + return NULL; } #endif /* CONFIG_TR */ @@ -223,14 +204,15 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc) * there is non-reboot way to recover if something goes wrong. */ -static int lec_open(struct net_device *dev) +static int +lec_open(struct net_device *dev) { - struct lec_priv *priv = (struct lec_priv *)dev->priv; - + struct lec_priv *priv = (struct lec_priv *)dev->priv; + netif_start_queue(dev); - memset(&priv->stats, 0, sizeof(struct net_device_stats)); - - return 0; + memset(&priv->stats,0,sizeof(struct net_device_stats)); + + return 0; } static __inline__ void @@ -249,166 +231,160 @@ lec_send(struct atm_vcc *vcc, struct sk_buff *skb, struct lec_priv *priv) priv->stats.tx_bytes += skb->len; } -static void lec_tx_timeout(struct net_device *dev) +static void +lec_tx_timeout(struct net_device *dev) { printk(KERN_INFO "%s: tx timeout\n", dev->name); dev->trans_start = jiffies; netif_wake_queue(dev); } -static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int +lec_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct sk_buff *skb2; - struct lec_priv *priv = (struct lec_priv *)dev->priv; - struct lecdatahdr_8023 *lec_h; - struct atm_vcc *vcc; + struct sk_buff *skb2; + struct lec_priv *priv = (struct lec_priv *)dev->priv; + struct lecdatahdr_8023 *lec_h; + struct atm_vcc *vcc; struct lec_arp_table *entry; - unsigned char *dst; + unsigned char *dst; int min_frame_size; #ifdef CONFIG_TR - unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */ + unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */ #endif - int is_rdesc; + int is_rdesc; #if DUMP_PACKETS > 0 - char buf[300]; - int i = 0; + char buf[300]; + int i=0; #endif /* DUMP_PACKETS >0 */ - - DPRINTK("lec_start_xmit called\n"); - if (!priv->lecd) { - printk("%s:No lecd attached\n", dev->name); - priv->stats.tx_errors++; - netif_stop_queue(dev); - return -EUNATCH; - } - - DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n", - (long)skb->head, (long)skb->data, (long)skb->tail, - (long)skb->end); + + DPRINTK("lec_start_xmit called\n"); + if (!priv->lecd) { + printk("%s:No lecd attached\n",dev->name); + priv->stats.tx_errors++; + netif_stop_queue(dev); + return -EUNATCH; + } + + DPRINTK("skbuff head:%lx data:%lx tail:%lx end:%lx\n", + (long)skb->head, (long)skb->data, (long)skb->tail, + (long)skb->end); #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) - if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0) - lec_handle_bridge(skb, dev); + if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0) + lec_handle_bridge(skb, dev); #endif - /* Make sure we have room for lec_id */ - if (skb_headroom(skb) < 2) { + /* Make sure we have room for lec_id */ + if (skb_headroom(skb) < 2) { - DPRINTK("lec_start_xmit: reallocating skb\n"); - skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); - kfree_skb(skb); - if (skb2 == NULL) - return 0; - skb = skb2; - } - skb_push(skb, 2); + DPRINTK("lec_start_xmit: reallocating skb\n"); + skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); + kfree_skb(skb); + if (skb2 == NULL) return 0; + skb = skb2; + } + skb_push(skb, 2); - /* Put le header to place, works for TokenRing too */ - lec_h = (struct lecdatahdr_8023 *)skb->data; - lec_h->le_header = htons(priv->lecid); + /* Put le header to place, works for TokenRing too */ + lec_h = (struct lecdatahdr_8023*)skb->data; + lec_h->le_header = htons(priv->lecid); #ifdef CONFIG_TR - /* - * Ugly. Use this to realign Token Ring packets for - * e.g. PCA-200E driver. - */ - if (priv->is_trdev) { - skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); - kfree_skb(skb); - if (skb2 == NULL) - return 0; - skb = skb2; - } + /* Ugly. Use this to realign Token Ring packets for + * e.g. PCA-200E driver. */ + if (priv->is_trdev) { + skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); + kfree_skb(skb); + if (skb2 == NULL) return 0; + skb = skb2; + } #endif #if DUMP_PACKETS > 0 - printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name, - skb->len, priv->lecid); + printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name, + skb->len, priv->lecid); #if DUMP_PACKETS >= 2 - for (i = 0; i < skb->len && i < 99; i++) { - sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]); - } + for(i=0;ilen && i <99;i++) { + sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]); + } #elif DUMP_PACKETS >= 1 - for (i = 0; i < skb->len && i < 30; i++) { - sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]); - } + for(i=0;ilen && i < 30;i++) { + sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]); + } #endif /* DUMP_PACKETS >= 1 */ - if (i == skb->len) - printk("%s\n", buf); - else - printk("%s...\n", buf); + if (i==skb->len) + printk("%s\n",buf); + else + printk("%s...\n",buf); #endif /* DUMP_PACKETS > 0 */ - /* Minimum ethernet-frame size */ + /* Minimum ethernet-frame size */ #ifdef CONFIG_TR - if (priv->is_trdev) - min_frame_size = LEC_MINIMUM_8025_SIZE; + if (priv->is_trdev) + min_frame_size = LEC_MINIMUM_8025_SIZE; else #endif - min_frame_size = LEC_MINIMUM_8023_SIZE; - if (skb->len < min_frame_size) { - if ((skb->len + skb_tailroom(skb)) < min_frame_size) { - skb2 = skb_copy_expand(skb, 0, - min_frame_size - skb->truesize, - GFP_ATOMIC); - dev_kfree_skb(skb); - if (skb2 == NULL) { - priv->stats.tx_dropped++; - return 0; - } - skb = skb2; - } + min_frame_size = LEC_MINIMUM_8023_SIZE; + if (skb->len < min_frame_size) { + if ((skb->len + skb_tailroom(skb)) < min_frame_size) { + skb2 = skb_copy_expand(skb, 0, + min_frame_size - skb->truesize, GFP_ATOMIC); + dev_kfree_skb(skb); + if (skb2 == NULL) { + priv->stats.tx_dropped++; + return 0; + } + skb = skb2; + } skb_put(skb, min_frame_size - skb->len); - } - - /* Send to right vcc */ - is_rdesc = 0; - dst = lec_h->h_dest; + } + + /* Send to right vcc */ + is_rdesc = 0; + dst = lec_h->h_dest; #ifdef CONFIG_TR - if (priv->is_trdev) { - dst = get_tr_dst(skb->data + 2, rdesc); - if (dst == NULL) { - dst = rdesc; - is_rdesc = 1; - } - } + if (priv->is_trdev) { + dst = get_tr_dst(skb->data+2, rdesc); + if (dst == NULL) { + dst = rdesc; + is_rdesc = 1; + } + } #endif - entry = NULL; - vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry); - DPRINTK("%s:vcc:%p vcc_flags:%x, entry:%p\n", dev->name, - vcc, vcc ? vcc->flags : 0, entry); - if (!vcc || !test_bit(ATM_VF_READY, &vcc->flags)) { - if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) { - DPRINTK("%s:lec_start_xmit: queuing packet, ", - dev->name); - DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - lec_h->h_dest[0], lec_h->h_dest[1], - lec_h->h_dest[2], lec_h->h_dest[3], - lec_h->h_dest[4], lec_h->h_dest[5]); - skb_queue_tail(&entry->tx_wait, skb); - } else { - DPRINTK - ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ", - dev->name); - DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - lec_h->h_dest[0], lec_h->h_dest[1], - lec_h->h_dest[2], lec_h->h_dest[3], - lec_h->h_dest[4], lec_h->h_dest[5]); - priv->stats.tx_dropped++; - dev_kfree_skb(skb); - } - goto out; - } -#if DUMP_PACKETS > 0 - printk("%s:sending to vpi:%d vci:%d\n", dev->name, vcc->vpi, vcc->vci); + entry = NULL; + vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry); + DPRINTK("%s:vcc:%p vcc_flags:%x, entry:%p\n", dev->name, + vcc, vcc?vcc->flags:0, entry); + if (!vcc || !test_bit(ATM_VF_READY,&vcc->flags)) { + if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) { + DPRINTK("%s:lec_start_xmit: queuing packet, ", dev->name); + DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", + lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2], + lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]); + skb_queue_tail(&entry->tx_wait, skb); + } else { + DPRINTK("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ", dev->name); + DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", + lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2], + lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]); + priv->stats.tx_dropped++; + dev_kfree_skb(skb); + } + return 0; + } + +#if DUMP_PACKETS > 0 + printk("%s:sending to vpi:%d vci:%d\n", dev->name, + vcc->vpi, vcc->vci); #endif /* DUMP_PACKETS > 0 */ - - while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) { - DPRINTK("lec.c: emptying tx queue, "); - DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2], - lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]); + + while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) { + DPRINTK("lec.c: emptying tx queue, "); + DPRINTK("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", + lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2], + lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]); lec_send(vcc, skb2, priv); - } + } lec_send(vcc, skb, priv); @@ -428,219 +404,210 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_wake_queue(dev); } -out: - if (entry) - lec_arp_put(entry); dev->trans_start = jiffies; - return 0; + return 0; } /* The inverse routine to net_open(). */ -static int lec_close(struct net_device *dev) +static int +lec_close(struct net_device *dev) { - netif_stop_queue(dev); - return 0; + netif_stop_queue(dev); + return 0; } /* * Get the current statistics. * This may be called with the card open or closed. */ -static struct net_device_stats *lec_get_stats(struct net_device *dev) +static struct net_device_stats * +lec_get_stats(struct net_device *dev) { - return &((struct lec_priv *)dev->priv)->stats; + return &((struct lec_priv *)dev->priv)->stats; } -static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) +static int +lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) { unsigned long flags; - struct net_device *dev = (struct net_device *)vcc->proto_data; - struct lec_priv *priv = (struct lec_priv *)dev->priv; - struct atmlec_msg *mesg; - struct lec_arp_table *entry; - int i; - char *tmp; /* FIXME */ + struct net_device *dev = (struct net_device*)vcc->proto_data; + struct lec_priv *priv = (struct lec_priv*)dev->priv; + struct atmlec_msg *mesg; + struct lec_arp_table *entry; + int i; + char *tmp; /* FIXME */ atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc); - mesg = (struct atmlec_msg *)skb->data; - tmp = skb->data; - tmp += sizeof(struct atmlec_msg); - DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type); - switch (mesg->type) { - case l_set_mac_addr: - for (i = 0; i < 6; i++) { - dev->dev_addr[i] = mesg->content.normal.mac_addr[i]; - } - break; - case l_del_mac_addr: - for (i = 0; i < 6; i++) { - dev->dev_addr[i] = 0; - } - break; - case l_addr_delete: - lec_addr_delete(priv, mesg->content.normal.atm_addr, - mesg->content.normal.flag); - break; - case l_topology_change: - priv->topology_change = mesg->content.normal.flag; - break; - case l_flush_complete: - lec_flush_complete(priv, mesg->content.normal.flag); - break; - case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */ + mesg = (struct atmlec_msg *)skb->data; + tmp = skb->data; + tmp += sizeof(struct atmlec_msg); + DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type); + switch(mesg->type) { + case l_set_mac_addr: + for (i=0;i<6;i++) { + dev->dev_addr[i] = mesg->content.normal.mac_addr[i]; + } + break; + case l_del_mac_addr: + for(i=0;i<6;i++) { + dev->dev_addr[i] = 0; + } + break; + case l_addr_delete: + lec_addr_delete(priv, mesg->content.normal.atm_addr, + mesg->content.normal.flag); + break; + case l_topology_change: + priv->topology_change = mesg->content.normal.flag; + break; + case l_flush_complete: + lec_flush_complete(priv, mesg->content.normal.flag); + break; + case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */ spin_lock_irqsave(&priv->lec_arp_lock, flags); - entry = lec_arp_find(priv, mesg->content.normal.mac_addr); - lec_arp_remove(priv, entry); + entry = lec_arp_find(priv, mesg->content.normal.mac_addr); + lec_arp_remove(priv, entry); spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - if (mesg->content.normal.no_source_le_narp) - break; - /* FALL THROUGH */ - case l_arp_update: - lec_arp_update(priv, mesg->content.normal.mac_addr, - mesg->content.normal.atm_addr, - mesg->content.normal.flag, - mesg->content.normal.targetless_le_arp); - DPRINTK("lec: in l_arp_update\n"); - if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */ - DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n", - mesg->sizeoftlvs); - lane2_associate_ind(dev, mesg->content.normal.mac_addr, - tmp, mesg->sizeoftlvs); - } - break; - case l_config: - priv->maximum_unknown_frame_count = - mesg->content.config.maximum_unknown_frame_count; - priv->max_unknown_frame_time = - (mesg->content.config.max_unknown_frame_time * HZ); - priv->max_retry_count = mesg->content.config.max_retry_count; - priv->aging_time = (mesg->content.config.aging_time * HZ); - priv->forward_delay_time = - (mesg->content.config.forward_delay_time * HZ); - priv->arp_response_time = - (mesg->content.config.arp_response_time * HZ); - priv->flush_timeout = (mesg->content.config.flush_timeout * HZ); - priv->path_switching_delay = - (mesg->content.config.path_switching_delay * HZ); - priv->lane_version = mesg->content.config.lane_version; /* LANE2 */ + if (mesg->content.normal.no_source_le_narp) + break; + /* FALL THROUGH */ + case l_arp_update: + lec_arp_update(priv, mesg->content.normal.mac_addr, + mesg->content.normal.atm_addr, + mesg->content.normal.flag, + mesg->content.normal.targetless_le_arp); + DPRINTK("lec: in l_arp_update\n"); + if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */ + DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n", mesg->sizeoftlvs); + lane2_associate_ind(dev, + mesg->content.normal.mac_addr, + tmp, mesg->sizeoftlvs); + } + break; + case l_config: + priv->maximum_unknown_frame_count = + mesg->content.config.maximum_unknown_frame_count; + priv->max_unknown_frame_time = + (mesg->content.config.max_unknown_frame_time*HZ); + priv->max_retry_count = + mesg->content.config.max_retry_count; + priv->aging_time = (mesg->content.config.aging_time*HZ); + priv->forward_delay_time = + (mesg->content.config.forward_delay_time*HZ); + priv->arp_response_time = + (mesg->content.config.arp_response_time*HZ); + priv->flush_timeout = (mesg->content.config.flush_timeout*HZ); + priv->path_switching_delay = + (mesg->content.config.path_switching_delay*HZ); + priv->lane_version = mesg->content.config.lane_version; /* LANE2 */ priv->lane2_ops = NULL; if (priv->lane_version > 1) priv->lane2_ops = &lane2_ops; if (dev->change_mtu(dev, mesg->content.config.mtu)) printk("%s: change_mtu to %d failed\n", dev->name, - mesg->content.config.mtu); + mesg->content.config.mtu); priv->is_proxy = mesg->content.config.is_proxy; - break; - case l_flush_tran_id: - lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr, - mesg->content.normal.flag); - break; - case l_set_lecid: - priv->lecid = - (unsigned short)(0xffff & mesg->content.normal.flag); - break; - case l_should_bridge: + break; + case l_flush_tran_id: + lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr, + mesg->content.normal.flag); + break; + case l_set_lecid: + priv->lecid=(unsigned short)(0xffff&mesg->content.normal.flag); + break; + case l_should_bridge: { #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) - { - struct net_bridge_fdb_entry *f; - - DPRINTK - ("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, mesg->content.proxy.mac_addr[0], - mesg->content.proxy.mac_addr[1], - mesg->content.proxy.mac_addr[2], - mesg->content.proxy.mac_addr[3], - mesg->content.proxy.mac_addr[4], - mesg->content.proxy.mac_addr[5]); - - if (br_fdb_get_hook == NULL || dev->br_port == NULL) - break; - - f = br_fdb_get_hook(dev->br_port->br, - mesg->content.proxy.mac_addr); - if (f != NULL && f->dst->dev != dev - && f->dst->state == BR_STATE_FORWARDING) { - /* hit from bridge table, send LE_ARP_RESPONSE */ - struct sk_buff *skb2; - struct sock *sk; - - DPRINTK - ("%s: entry found, responding to zeppelin\n", - dev->name); - skb2 = - alloc_skb(sizeof(struct atmlec_msg), - GFP_ATOMIC); - if (skb2 == NULL) { - br_fdb_put_hook(f); - break; - } - skb2->len = sizeof(struct atmlec_msg); - memcpy(skb2->data, mesg, - sizeof(struct atmlec_msg)); - atm_force_charge(priv->lecd, skb2->truesize); - sk = sk_atm(priv->lecd); - skb_queue_tail(&sk->sk_receive_queue, skb2); - sk->sk_data_ready(sk, skb2->len); - } - if (f != NULL) - br_fdb_put_hook(f); - } + struct net_bridge_fdb_entry *f; + + DPRINTK("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, + mesg->content.proxy.mac_addr[0], mesg->content.proxy.mac_addr[1], + mesg->content.proxy.mac_addr[2], mesg->content.proxy.mac_addr[3], + mesg->content.proxy.mac_addr[4], mesg->content.proxy.mac_addr[5]); + + if (br_fdb_get_hook == NULL || dev->br_port == NULL) + break; + + f = br_fdb_get_hook(dev->br_port->br, mesg->content.proxy.mac_addr); + if (f != NULL && + f->dst->dev != dev && + f->dst->state == BR_STATE_FORWARDING) { + /* hit from bridge table, send LE_ARP_RESPONSE */ + struct sk_buff *skb2; + struct sock *sk; + + DPRINTK("%s: entry found, responding to zeppelin\n", dev->name); + skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC); + if (skb2 == NULL) { + br_fdb_put_hook(f); + break; + } + skb2->len = sizeof(struct atmlec_msg); + memcpy(skb2->data, mesg, sizeof(struct atmlec_msg)); + atm_force_charge(priv->lecd, skb2->truesize); + sk = sk_atm(priv->lecd); + skb_queue_tail(&sk->sk_receive_queue, skb2); + sk->sk_data_ready(sk, skb2->len); + } + if (f != NULL) br_fdb_put_hook(f); #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */ - break; - default: - printk("%s: Unknown message type %d\n", dev->name, mesg->type); - dev_kfree_skb(skb); - return -EINVAL; - } - dev_kfree_skb(skb); - return 0; + } + break; + default: + printk("%s: Unknown message type %d\n", dev->name, mesg->type); + dev_kfree_skb(skb); + return -EINVAL; + } + dev_kfree_skb(skb); + return 0; } -static void lec_atm_close(struct atm_vcc *vcc) +static void +lec_atm_close(struct atm_vcc *vcc) { - struct sk_buff *skb; - struct net_device *dev = (struct net_device *)vcc->proto_data; - struct lec_priv *priv = (struct lec_priv *)dev->priv; + struct sk_buff *skb; + struct net_device *dev = (struct net_device *)vcc->proto_data; + struct lec_priv *priv = (struct lec_priv *)dev->priv; - priv->lecd = NULL; - /* Do something needful? */ + priv->lecd = NULL; + /* Do something needful? */ - netif_stop_queue(dev); - lec_arp_destroy(priv); + netif_stop_queue(dev); + lec_arp_destroy(priv); - if (skb_peek(&sk_atm(vcc)->sk_receive_queue)) + if (skb_peek(&sk_atm(vcc)->sk_receive_queue)) printk("%s lec_atm_close: closing with messages pending\n", - dev->name); - while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) { - atm_return(vcc, skb->truesize); + dev->name); + while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) { + atm_return(vcc, skb->truesize); dev_kfree_skb(skb); - } - + } + printk("%s: Shut down!\n", dev->name); - module_put(THIS_MODULE); + module_put(THIS_MODULE); } static struct atmdev_ops lecdev_ops = { - .close = lec_atm_close, - .send = lec_atm_send + .close = lec_atm_close, + .send = lec_atm_send }; static struct atm_dev lecatm_dev = { - .ops = &lecdev_ops, - .type = "lec", - .number = 999, /* dummy device number */ - .lock = SPIN_LOCK_UNLOCKED + .ops = &lecdev_ops, + .type = "lec", + .number = 999, /* dummy device number */ + .lock = SPIN_LOCK_UNLOCKED }; /* * LANE2: new argument struct sk_buff *data contains * the LE_ARP based TLVs introduced in the LANE2 spec */ -static int -send_to_lecd(struct lec_priv *priv, atmlec_msg_type type, - unsigned char *mac_addr, unsigned char *atm_addr, - struct sk_buff *data) +static int +send_to_lecd(struct lec_priv *priv, atmlec_msg_type type, + unsigned char *mac_addr, unsigned char *atm_addr, + struct sk_buff *data) { struct sock *sk; struct sk_buff *skb; @@ -654,193 +621,187 @@ send_to_lecd(struct lec_priv *priv, atmlec_msg_type type, return -1; skb->len = sizeof(struct atmlec_msg); mesg = (struct atmlec_msg *)skb->data; - memset(mesg, 0, sizeof(struct atmlec_msg)); + memset(mesg, 0, sizeof(struct atmlec_msg)); mesg->type = type; - if (data != NULL) - mesg->sizeoftlvs = data->len; + if (data != NULL) + mesg->sizeoftlvs = data->len; if (mac_addr) memcpy(&mesg->content.normal.mac_addr, mac_addr, ETH_ALEN); - else - mesg->content.normal.targetless_le_arp = 1; + else + mesg->content.normal.targetless_le_arp = 1; if (atm_addr) memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN); - atm_force_charge(priv->lecd, skb->truesize); + atm_force_charge(priv->lecd, skb->truesize); sk = sk_atm(priv->lecd); skb_queue_tail(&sk->sk_receive_queue, skb); - sk->sk_data_ready(sk, skb->len); + sk->sk_data_ready(sk, skb->len); - if (data != NULL) { - DPRINTK("lec: about to send %d bytes of data\n", data->len); - atm_force_charge(priv->lecd, data->truesize); - skb_queue_tail(&sk->sk_receive_queue, data); - sk->sk_data_ready(sk, skb->len); - } + if (data != NULL) { + DPRINTK("lec: about to send %d bytes of data\n", data->len); + atm_force_charge(priv->lecd, data->truesize); + skb_queue_tail(&sk->sk_receive_queue, data); + sk->sk_data_ready(sk, skb->len); + } - return 0; + return 0; } /* shamelessly stolen from drivers/net/net_init.c */ static int lec_change_mtu(struct net_device *dev, int new_mtu) { - if ((new_mtu < 68) || (new_mtu > 18190)) - return -EINVAL; - dev->mtu = new_mtu; - return 0; + if ((new_mtu < 68) || (new_mtu > 18190)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; } static void lec_set_multicast_list(struct net_device *dev) { - /* - * by default, all multicast frames arrive over the bus. - * eventually support selective multicast service - */ - return; + /* by default, all multicast frames arrive over the bus. + * eventually support selective multicast service + */ + return; } -static void lec_init(struct net_device *dev) +static void +lec_init(struct net_device *dev) { - dev->change_mtu = lec_change_mtu; - dev->open = lec_open; - dev->stop = lec_close; - dev->hard_start_xmit = lec_start_xmit; + dev->change_mtu = lec_change_mtu; + dev->open = lec_open; + dev->stop = lec_close; + dev->hard_start_xmit = lec_start_xmit; dev->tx_timeout = lec_tx_timeout; - dev->get_stats = lec_get_stats; - dev->set_multicast_list = lec_set_multicast_list; - dev->do_ioctl = NULL; - printk("%s: Initialized!\n", dev->name); - return; + dev->get_stats = lec_get_stats; + dev->set_multicast_list = lec_set_multicast_list; + dev->do_ioctl = NULL; + printk("%s: Initialized!\n",dev->name); + return; } static unsigned char lec_ctrl_magic[] = { - 0xff, - 0x00, - 0x01, - 0x01 -}; + 0xff, + 0x00, + 0x01, + 0x01 }; #define LEC_DATA_DIRECT_8023 2 #define LEC_DATA_DIRECT_8025 3 static int lec_is_data_direct(struct atm_vcc *vcc) -{ +{ return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) || (vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025)); -} +} -static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb) +static void +lec_push(struct atm_vcc *vcc, struct sk_buff *skb) { unsigned long flags; - struct net_device *dev = (struct net_device *)vcc->proto_data; - struct lec_priv *priv = (struct lec_priv *)dev->priv; + struct net_device *dev = (struct net_device *)vcc->proto_data; + struct lec_priv *priv = (struct lec_priv *)dev->priv; #if DUMP_PACKETS >0 - int i = 0; - char buf[300]; + int i=0; + char buf[300]; - printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name, - vcc->vpi, vcc->vci); + printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name, + vcc->vpi, vcc->vci); #endif - if (!skb) { - DPRINTK("%s: null skb\n", dev->name); - lec_vcc_close(priv, vcc); - return; - } + if (!skb) { + DPRINTK("%s: null skb\n",dev->name); + lec_vcc_close(priv, vcc); + return; + } #if DUMP_PACKETS > 0 - printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name, - skb->len, priv->lecid); + printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name, + skb->len, priv->lecid); #if DUMP_PACKETS >= 2 - for (i = 0; i < skb->len && i < 99; i++) { - sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]); - } + for(i=0;ilen && i <99;i++) { + sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]); + } #elif DUMP_PACKETS >= 1 - for (i = 0; i < skb->len && i < 30; i++) { - sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]); - } + for(i=0;ilen && i < 30;i++) { + sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]); + } #endif /* DUMP_PACKETS >= 1 */ - if (i == skb->len) - printk("%s\n", buf); - else - printk("%s...\n", buf); + if (i==skb->len) + printk("%s\n",buf); + else + printk("%s...\n",buf); #endif /* DUMP_PACKETS > 0 */ - if (memcmp(skb->data, lec_ctrl_magic, 4) == 0) { /* Control frame, to daemon */ + if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/ struct sock *sk = sk_atm(vcc); - DPRINTK("%s: To daemon\n", dev->name); - skb_queue_tail(&sk->sk_receive_queue, skb); - sk->sk_data_ready(sk, skb->len); - } else { /* Data frame, queue to protocol handlers */ + DPRINTK("%s: To daemon\n",dev->name); + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); + } else { /* Data frame, queue to protocol handlers */ struct lec_arp_table *entry; - unsigned char *src, *dst; - - atm_return(vcc, skb->truesize); - if (*(uint16_t *) skb->data == htons(priv->lecid) || - !priv->lecd || !(dev->flags & IFF_UP)) { - /* - * Probably looping back, or if lecd is missing, - * lecd has gone down - */ - DPRINTK("Ignoring frame...\n"); - dev_kfree_skb(skb); - return; - } + unsigned char *src, *dst; + + atm_return(vcc,skb->truesize); + if (*(uint16_t *)skb->data == htons(priv->lecid) || + !priv->lecd || + !(dev->flags & IFF_UP)) { + /* Probably looping back, or if lecd is missing, + lecd has gone down */ + DPRINTK("Ignoring frame...\n"); + dev_kfree_skb(skb); + return; + } #ifdef CONFIG_TR - if (priv->is_trdev) - dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest; - else + if (priv->is_trdev) + dst = ((struct lecdatahdr_8025 *) skb->data)->h_dest; + else #endif - dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; + dst = ((struct lecdatahdr_8023 *) skb->data)->h_dest; - /* - * If this is a Data Direct VCC, and the VCC does not match + /* If this is a Data Direct VCC, and the VCC does not match * the LE_ARP cache entry, delete the LE_ARP cache entry. */ spin_lock_irqsave(&priv->lec_arp_lock, flags); if (lec_is_data_direct(vcc)) { #ifdef CONFIG_TR if (priv->is_trdev) - src = - ((struct lecdatahdr_8025 *)skb->data)-> - h_source; + src = ((struct lecdatahdr_8025 *) skb->data)->h_source; else #endif - src = - ((struct lecdatahdr_8023 *)skb->data)-> - h_source; + src = ((struct lecdatahdr_8023 *) skb->data)->h_source; entry = lec_arp_find(priv, src); if (entry && entry->vcc != vcc) { lec_arp_remove(priv, entry); - lec_arp_put(entry); + kfree(entry); } } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - if (!(dst[0] & 0x01) && /* Never filter Multi/Broadcast */ - !priv->is_proxy && /* Proxy wants all the packets */ + if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */ + !priv->is_proxy && /* Proxy wants all the packets */ memcmp(dst, dev->dev_addr, dev->addr_len)) { - dev_kfree_skb(skb); - return; - } - if (!hlist_empty(&priv->lec_arp_empty_ones)) { - lec_arp_check_empties(priv, vcc, skb); - } - skb->dev = dev; - skb_pull(skb, 2); /* skip lec_id */ + dev_kfree_skb(skb); + return; + } + if (priv->lec_arp_empty_ones) { + lec_arp_check_empties(priv, vcc, skb); + } + skb->dev = dev; + skb_pull(skb, 2); /* skip lec_id */ #ifdef CONFIG_TR - if (priv->is_trdev) - skb->protocol = tr_type_trans(skb, dev); - else + if (priv->is_trdev) skb->protocol = tr_type_trans(skb, dev); + else #endif - skb->protocol = eth_type_trans(skb, dev); - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; - memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); - netif_rx(skb); - } + skb->protocol = eth_type_trans(skb, dev); + priv->stats.rx_packets++; + priv->stats.rx_bytes += skb->len; + memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); + netif_rx(skb); + } } -static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb) +static void +lec_pop(struct atm_vcc *vcc, struct sk_buff *skb) { struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); struct net_device *dev = skb->dev; @@ -859,121 +820,123 @@ static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb) } } -static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) +static int +lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) { struct lec_vcc_priv *vpriv; - int bytes_left; - struct atmlec_ioc ioc_data; - - /* Lecd must be up in this case */ - bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc)); - if (bytes_left != 0) { - printk - ("lec: lec_vcc_attach, copy from user failed for %d bytes\n", - bytes_left); - } - if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF || - !dev_lec[ioc_data.dev_num]) - return -EINVAL; + int bytes_left; + struct atmlec_ioc ioc_data; + + /* Lecd must be up in this case */ + bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc)); + if (bytes_left != 0) { + printk("lec: lec_vcc_attach, copy from user failed for %d bytes\n", + bytes_left); + } + if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF || + !dev_lec[ioc_data.dev_num]) + return -EINVAL; if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL))) return -ENOMEM; vpriv->xoff = 0; vpriv->old_pop = vcc->pop; vcc->user_back = vpriv; vcc->pop = lec_pop; - lec_vcc_added(dev_lec[ioc_data.dev_num]->priv, - &ioc_data, vcc, vcc->push); - vcc->proto_data = dev_lec[ioc_data.dev_num]; - vcc->push = lec_push; - return 0; + lec_vcc_added(dev_lec[ioc_data.dev_num]->priv, + &ioc_data, vcc, vcc->push); + vcc->proto_data = dev_lec[ioc_data.dev_num]; + vcc->push = lec_push; + return 0; } -static int lec_mcast_attach(struct atm_vcc *vcc, int arg) +static int +lec_mcast_attach(struct atm_vcc *vcc, int arg) { - if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg]) - return -EINVAL; - vcc->proto_data = dev_lec[arg]; - return (lec_mcast_make((struct lec_priv *)dev_lec[arg]->priv, vcc)); + if (arg <0 || arg >= MAX_LEC_ITF || !dev_lec[arg]) + return -EINVAL; + vcc->proto_data = dev_lec[arg]; + return (lec_mcast_make((struct lec_priv*)dev_lec[arg]->priv, vcc)); } /* Initialize device. */ -static int lecd_attach(struct atm_vcc *vcc, int arg) -{ - int i; - struct lec_priv *priv; - - if (arg < 0) - i = 0; - else - i = arg; +static int +lecd_attach(struct atm_vcc *vcc, int arg) +{ + int i; + struct lec_priv *priv; + + if (arg<0) + i = 0; + else + i = arg; #ifdef CONFIG_TR - if (arg >= MAX_LEC_ITF) - return -EINVAL; -#else /* Reserve the top NUM_TR_DEVS for TR */ - if (arg >= (MAX_LEC_ITF - NUM_TR_DEVS)) - return -EINVAL; + if (arg >= MAX_LEC_ITF) + return -EINVAL; +#else /* Reserve the top NUM_TR_DEVS for TR */ + if (arg >= (MAX_LEC_ITF-NUM_TR_DEVS)) + return -EINVAL; #endif - if (!dev_lec[i]) { - int is_trdev, size; + if (!dev_lec[i]) { + int is_trdev, size; - is_trdev = 0; - if (i >= (MAX_LEC_ITF - NUM_TR_DEVS)) - is_trdev = 1; + is_trdev = 0; + if (i >= (MAX_LEC_ITF - NUM_TR_DEVS)) + is_trdev = 1; - size = sizeof(struct lec_priv); + size = sizeof(struct lec_priv); #ifdef CONFIG_TR - if (is_trdev) - dev_lec[i] = alloc_trdev(size); - else + if (is_trdev) + dev_lec[i] = alloc_trdev(size); + else #endif - dev_lec[i] = alloc_etherdev(size); - if (!dev_lec[i]) - return -ENOMEM; - snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i); - if (register_netdev(dev_lec[i])) { - free_netdev(dev_lec[i]); - return -EINVAL; - } - - priv = dev_lec[i]->priv; - priv->is_trdev = is_trdev; - lec_init(dev_lec[i]); - } else { - priv = dev_lec[i]->priv; - if (priv->lecd) - return -EADDRINUSE; - } - lec_arp_init(priv); - priv->itfnum = i; /* LANE2 addition */ - priv->lecd = vcc; - vcc->dev = &lecatm_dev; - vcc_insert_socket(sk_atm(vcc)); - - vcc->proto_data = dev_lec[i]; - set_bit(ATM_VF_META, &vcc->flags); - set_bit(ATM_VF_READY, &vcc->flags); - - /* Set default values to these variables */ - priv->maximum_unknown_frame_count = 1; - priv->max_unknown_frame_time = (1 * HZ); - priv->vcc_timeout_period = (1200 * HZ); - priv->max_retry_count = 1; - priv->aging_time = (300 * HZ); - priv->forward_delay_time = (15 * HZ); - priv->topology_change = 0; - priv->arp_response_time = (1 * HZ); - priv->flush_timeout = (4 * HZ); - priv->path_switching_delay = (6 * HZ); - - if (dev_lec[i]->flags & IFF_UP) { - netif_start_queue(dev_lec[i]); - } - __module_get(THIS_MODULE); - return i; + dev_lec[i] = alloc_etherdev(size); + if (!dev_lec[i]) + return -ENOMEM; + snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i); + if (register_netdev(dev_lec[i])) { + free_netdev(dev_lec[i]); + return -EINVAL; + } + + priv = dev_lec[i]->priv; + priv->is_trdev = is_trdev; + lec_init(dev_lec[i]); + } else { + priv = dev_lec[i]->priv; + if (priv->lecd) + return -EADDRINUSE; + } + lec_arp_init(priv); + priv->itfnum = i; /* LANE2 addition */ + priv->lecd = vcc; + vcc->dev = &lecatm_dev; + vcc_insert_socket(sk_atm(vcc)); + + vcc->proto_data = dev_lec[i]; + set_bit(ATM_VF_META,&vcc->flags); + set_bit(ATM_VF_READY,&vcc->flags); + + /* Set default values to these variables */ + priv->maximum_unknown_frame_count = 1; + priv->max_unknown_frame_time = (1*HZ); + priv->vcc_timeout_period = (1200*HZ); + priv->max_retry_count = 1; + priv->aging_time = (300*HZ); + priv->forward_delay_time = (15*HZ); + priv->topology_change = 0; + priv->arp_response_time = (1*HZ); + priv->flush_timeout = (4*HZ); + priv->path_switching_delay = (6*HZ); + + if (dev_lec[i]->flags & IFF_UP) { + netif_start_queue(dev_lec[i]); + } + __module_get(THIS_MODULE); + return i; } #ifdef CONFIG_PROC_FS -static char *lec_arp_get_status_string(unsigned char status) +static char* lec_arp_get_status_string(unsigned char status) { static char *lec_arp_status_string[] = { "ESI_UNKNOWN ", @@ -1003,54 +966,52 @@ static void lec_info(struct seq_file *seq, struct lec_arp_table *entry) if (entry->vcc) seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci); else - seq_printf(seq, " "); + seq_printf(seq, " "); if (entry->recv_vcc) { seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi, entry->recv_vcc->vci); - } - seq_putc(seq, '\n'); + } + seq_putc(seq, '\n'); } + struct lec_state { unsigned long flags; struct lec_priv *locked; - struct hlist_node *node; + struct lec_arp_table *entry; struct net_device *dev; int itf; int arp_table; int misc_table; }; -static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl, +static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl, loff_t *l) { - struct hlist_node *e = state->node; - struct lec_arp_table *tmp; + struct lec_arp_table *e = state->entry; if (!e) - e = tbl->first; + e = tbl; if (e == (void *)1) { - e = tbl->first; + e = tbl; --*l; } - - hlist_for_each_entry_from(tmp, e, next) { + for (; e; e = e->next) { if (--*l < 0) break; } - state->node = e; - + state->entry = e; return (*l < 0) ? state : NULL; } static void *lec_arp_walk(struct lec_state *state, loff_t *l, - struct lec_priv *priv) + struct lec_priv *priv) { void *v = NULL; int p; for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) { - v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l); + v = lec_tbl_walk(state, priv->lec_arp_tables[p], l); if (v) break; } @@ -1061,10 +1022,10 @@ static void *lec_arp_walk(struct lec_state *state, loff_t *l, static void *lec_misc_walk(struct lec_state *state, loff_t *l, struct lec_priv *priv) { - struct hlist_head *lec_misc_tables[] = { - &priv->lec_arp_empty_ones, - &priv->lec_no_forward, - &priv->mcast_fwds + struct lec_arp_table *lec_misc_tables[] = { + priv->lec_arp_empty_ones, + priv->lec_no_forward, + priv->mcast_fwds }; void *v = NULL; int q; @@ -1085,7 +1046,8 @@ static void *lec_priv_walk(struct lec_state *state, loff_t *l, state->locked = priv; spin_lock_irqsave(&priv->lec_arp_lock, state->flags); } - if (!lec_arp_walk(state, l, priv) && !lec_misc_walk(state, l, priv)) { + if (!lec_arp_walk(state, l, priv) && + !lec_misc_walk(state, l, priv)) { spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags); state->locked = NULL; /* Partial state reset for the next time we get called */ @@ -1119,7 +1081,7 @@ static void *lec_get_idx(struct lec_state *state, loff_t l) if (v) break; } - return v; + return v; } static void *lec_seq_start(struct seq_file *seq, loff_t *pos) @@ -1131,9 +1093,9 @@ static void *lec_seq_start(struct seq_file *seq, loff_t *pos) state->locked = NULL; state->arp_table = 0; state->misc_table = 0; - state->node = (void *)1; + state->entry = (void *)1; - return *pos ? lec_get_idx(state, *pos) : (void *)1; + return *pos ? lec_get_idx(state, *pos) : (void*)1; } static void lec_seq_stop(struct seq_file *seq, void *v) @@ -1158,28 +1120,27 @@ static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos) static int lec_seq_show(struct seq_file *seq, void *v) { - static char lec_banner[] = "Itf MAC ATM destination" - " Status Flags " - "VPI/VCI Recv VPI/VCI\n"; + static char lec_banner[] = "Itf MAC ATM destination" + " Status Flags " + "VPI/VCI Recv VPI/VCI\n"; if (v == (void *)1) seq_puts(seq, lec_banner); else { struct lec_state *state = seq->private; - struct net_device *dev = state->dev; - struct lec_arp_table *entry = hlist_entry(state->node, struct lec_arp_table, next); + struct net_device *dev = state->dev; seq_printf(seq, "%s ", dev->name); - lec_info(seq, entry); + lec_info(seq, state->entry); } return 0; } static struct seq_operations lec_seq_ops = { - .start = lec_seq_start, - .next = lec_seq_next, - .stop = lec_seq_stop, - .show = lec_seq_show, + .start = lec_seq_start, + .next = lec_seq_next, + .stop = lec_seq_stop, + .show = lec_seq_show, }; static int lec_seq_open(struct inode *inode, struct file *file) @@ -1213,11 +1174,11 @@ static int lec_seq_release(struct inode *inode, struct file *file) } static struct file_operations lec_seq_fops = { - .owner = THIS_MODULE, - .open = lec_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = lec_seq_release, + .owner = THIS_MODULE, + .open = lec_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = lec_seq_release, }; #endif @@ -1225,38 +1186,38 @@ static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct atm_vcc *vcc = ATM_SD(sock); int err = 0; - + switch (cmd) { - case ATMLEC_CTRL: - case ATMLEC_MCAST: - case ATMLEC_DATA: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - break; - default: - return -ENOIOCTLCMD; + case ATMLEC_CTRL: + case ATMLEC_MCAST: + case ATMLEC_DATA: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + break; + default: + return -ENOIOCTLCMD; } switch (cmd) { - case ATMLEC_CTRL: - err = lecd_attach(vcc, (int)arg); - if (err >= 0) - sock->state = SS_CONNECTED; - break; - case ATMLEC_MCAST: - err = lec_mcast_attach(vcc, (int)arg); - break; - case ATMLEC_DATA: - err = lec_vcc_attach(vcc, (void __user *)arg); - break; + case ATMLEC_CTRL: + err = lecd_attach(vcc, (int) arg); + if (err >= 0) + sock->state = SS_CONNECTED; + break; + case ATMLEC_MCAST: + err = lec_mcast_attach(vcc, (int) arg); + break; + case ATMLEC_DATA: + err = lec_vcc_attach(vcc, (void __user *) arg); + break; } return err; } static struct atm_ioctl lane_ioctl_ops = { - .owner = THIS_MODULE, - .ioctl = lane_ioctl, + .owner = THIS_MODULE, + .ioctl = lane_ioctl, }; static int __init lane_module_init(void) @@ -1270,29 +1231,29 @@ static int __init lane_module_init(void) #endif register_atm_ioctl(&lane_ioctl_ops); - printk("lec.c: " __DATE__ " " __TIME__ " initialized\n"); - return 0; + printk("lec.c: " __DATE__ " " __TIME__ " initialized\n"); + return 0; } static void __exit lane_module_cleanup(void) { - int i; - struct lec_priv *priv; + int i; + struct lec_priv *priv; remove_proc_entry("lec", atm_proc_root); deregister_atm_ioctl(&lane_ioctl_ops); - for (i = 0; i < MAX_LEC_ITF; i++) { - if (dev_lec[i] != NULL) { - priv = (struct lec_priv *)dev_lec[i]->priv; + for (i = 0; i < MAX_LEC_ITF; i++) { + if (dev_lec[i] != NULL) { + priv = (struct lec_priv *)dev_lec[i]->priv; unregister_netdev(dev_lec[i]); - free_netdev(dev_lec[i]); - dev_lec[i] = NULL; - } - } + free_netdev(dev_lec[i]); + dev_lec[i] = NULL; + } + } - return; + return; } module_init(lane_module_init); @@ -1306,34 +1267,34 @@ module_exit(lane_module_cleanup); * If dst_mac == NULL, targetless LE_ARP will be sent */ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force, - u8 **tlvs, u32 *sizeoftlvs) + u8 **tlvs, u32 *sizeoftlvs) { unsigned long flags; - struct lec_priv *priv = (struct lec_priv *)dev->priv; - struct lec_arp_table *table; - struct sk_buff *skb; - int retval; + struct lec_priv *priv = (struct lec_priv *)dev->priv; + struct lec_arp_table *table; + struct sk_buff *skb; + int retval; - if (force == 0) { + if (force == 0) { spin_lock_irqsave(&priv->lec_arp_lock, flags); - table = lec_arp_find(priv, dst_mac); + table = lec_arp_find(priv, dst_mac); spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - if (table == NULL) - return -1; - - *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC); - if (*tlvs == NULL) - return -1; - - memcpy(*tlvs, table->tlvs, table->sizeoftlvs); - *sizeoftlvs = table->sizeoftlvs; - - return 0; - } + if(table == NULL) + return -1; + + *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC); + if (*tlvs == NULL) + return -1; + + memcpy(*tlvs, table->tlvs, table->sizeoftlvs); + *sizeoftlvs = table->sizeoftlvs; + + return 0; + } if (sizeoftlvs == NULL) retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL); - + else { skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC); if (skb == NULL) @@ -1342,8 +1303,9 @@ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force, memcpy(skb->data, *tlvs, *sizeoftlvs); retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb); } - return retval; -} + return retval; +} + /* * LANE2: 3.1.4, LE_ASSOCIATE.request @@ -1352,85 +1314,80 @@ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force, * Returns 1 for success, 0 for failure (out of memory) * */ -static int lane2_associate_req(struct net_device *dev, u8 *lan_dst, - u8 *tlvs, u32 sizeoftlvs) +static int lane2_associate_req (struct net_device *dev, u8 *lan_dst, + u8 *tlvs, u32 sizeoftlvs) { - int retval; - struct sk_buff *skb; - struct lec_priv *priv = (struct lec_priv *)dev->priv; - - if (compare_ether_addr(lan_dst, dev->dev_addr)) - return (0); /* not our mac address */ - - kfree(priv->tlvs); /* NULL if there was no previous association */ - - priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL); - if (priv->tlvs == NULL) - return (0); - priv->sizeoftlvs = sizeoftlvs; - memcpy(priv->tlvs, tlvs, sizeoftlvs); - - skb = alloc_skb(sizeoftlvs, GFP_ATOMIC); - if (skb == NULL) - return 0; - skb->len = sizeoftlvs; - memcpy(skb->data, tlvs, sizeoftlvs); - retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb); - if (retval != 0) - printk("lec.c: lane2_associate_req() failed\n"); - /* - * If the previous association has changed we must - * somehow notify other LANE entities about the change - */ - return (1); + int retval; + struct sk_buff *skb; + struct lec_priv *priv = (struct lec_priv*)dev->priv; + + if (compare_ether_addr(lan_dst, dev->dev_addr)) + return (0); /* not our mac address */ + + kfree(priv->tlvs); /* NULL if there was no previous association */ + + priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL); + if (priv->tlvs == NULL) + return (0); + priv->sizeoftlvs = sizeoftlvs; + memcpy(priv->tlvs, tlvs, sizeoftlvs); + + skb = alloc_skb(sizeoftlvs, GFP_ATOMIC); + if (skb == NULL) + return 0; + skb->len = sizeoftlvs; + memcpy(skb->data, tlvs, sizeoftlvs); + retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb); + if (retval != 0) + printk("lec.c: lane2_associate_req() failed\n"); + /* If the previous association has changed we must + * somehow notify other LANE entities about the change + */ + return (1); } /* * LANE2: 3.1.5, LE_ASSOCIATE.indication * */ -static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, - u8 *tlvs, u32 sizeoftlvs) +static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr, + u8 *tlvs, u32 sizeoftlvs) { #if 0 - int i = 0; + int i = 0; #endif struct lec_priv *priv = (struct lec_priv *)dev->priv; -#if 0 /* - * Why have the TLVs in LE_ARP entries - * since we do not use them? When you - * uncomment this code, make sure the - * TLVs get freed when entry is killed - */ - struct lec_arp_table *entry = lec_arp_find(priv, mac_addr); +#if 0 /* Why have the TLVs in LE_ARP entries since we do not use them? When you + uncomment this code, make sure the TLVs get freed when entry is killed */ + struct lec_arp_table *entry = lec_arp_find(priv, mac_addr); - if (entry == NULL) - return; /* should not happen */ + if (entry == NULL) + return; /* should not happen */ - kfree(entry->tlvs); + kfree(entry->tlvs); - entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL); - if (entry->tlvs == NULL) - return; + entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL); + if (entry->tlvs == NULL) + return; - entry->sizeoftlvs = sizeoftlvs; - memcpy(entry->tlvs, tlvs, sizeoftlvs); + entry->sizeoftlvs = sizeoftlvs; + memcpy(entry->tlvs, tlvs, sizeoftlvs); #endif #if 0 - printk("lec.c: lane2_associate_ind()\n"); - printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs); - while (i < sizeoftlvs) - printk("%02x ", tlvs[i++]); - - printk("\n"); + printk("lec.c: lane2_associate_ind()\n"); + printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs); + while (i < sizeoftlvs) + printk("%02x ", tlvs[i++]); + + printk("\n"); #endif - /* tell MPOA about the TLVs we saw */ - if (priv->lane2_ops && priv->lane2_ops->associate_indicator) { - priv->lane2_ops->associate_indicator(dev, mac_addr, - tlvs, sizeoftlvs); - } - return; + /* tell MPOA about the TLVs we saw */ + if (priv->lane2_ops && priv->lane2_ops->associate_indicator) { + priv->lane2_ops->associate_indicator(dev, mac_addr, + tlvs, sizeoftlvs); + } + return; } /* @@ -1438,6 +1395,7 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, * * lec_arpc.c was added here when making * lane client modular. October 1997 + * */ #include @@ -1448,6 +1406,7 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, #include #include + #if 0 #define DPRINTK(format,args...) /* @@ -1458,7 +1417,7 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, #define LEC_ARP_REFRESH_INTERVAL (3*HZ) -static void lec_arp_check_expire(void *data); +static void lec_arp_check_expire(unsigned long data); static void lec_arp_expire_arp(unsigned long data); /* @@ -1470,397 +1429,474 @@ static void lec_arp_expire_arp(unsigned long data); /* * Initialization of arp-cache */ -static void lec_arp_init(struct lec_priv *priv) +static void +lec_arp_init(struct lec_priv *priv) { - unsigned short i; + unsigned short i; - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - INIT_HLIST_HEAD(&priv->lec_arp_tables[i]); - } - INIT_HLIST_HEAD(&priv->lec_arp_empty_ones); - INIT_HLIST_HEAD(&priv->lec_no_forward); - INIT_HLIST_HEAD(&priv->mcast_fwds); + for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { + priv->lec_arp_tables[i] = NULL; + } spin_lock_init(&priv->lec_arp_lock); - INIT_WORK(&priv->lec_arp_work, lec_arp_check_expire, priv); - schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL); + init_timer(&priv->lec_arp_timer); + priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL; + priv->lec_arp_timer.data = (unsigned long)priv; + priv->lec_arp_timer.function = lec_arp_check_expire; + add_timer(&priv->lec_arp_timer); } -static void lec_arp_clear_vccs(struct lec_arp_table *entry) +static void +lec_arp_clear_vccs(struct lec_arp_table *entry) { - if (entry->vcc) { + if (entry->vcc) { struct atm_vcc *vcc = entry->vcc; struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); - struct net_device *dev = (struct net_device *)vcc->proto_data; + struct net_device *dev = (struct net_device*) vcc->proto_data; - vcc->pop = vpriv->old_pop; + vcc->pop = vpriv->old_pop; if (vpriv->xoff) netif_wake_queue(dev); kfree(vpriv); vcc->user_back = NULL; - vcc->push = entry->old_push; + vcc->push = entry->old_push; vcc_release_async(vcc, -EPIPE); - entry->vcc = NULL; - } - if (entry->recv_vcc) { - entry->recv_vcc->push = entry->old_recv_push; + vcc = NULL; + } + if (entry->recv_vcc) { + entry->recv_vcc->push = entry->old_recv_push; vcc_release_async(entry->recv_vcc, -EPIPE); - entry->recv_vcc = NULL; - } + entry->recv_vcc = NULL; + } } /* * Insert entry to lec_arp_table * LANE2: Add to the end of the list to satisfy 8.1.13 */ -static inline void -lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry) +static inline void +lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add) { - struct hlist_head *tmp; - - tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])]; - hlist_add_head(&entry->next, tmp); - - DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - 0xff & entry->mac_addr[0], 0xff & entry->mac_addr[1], - 0xff & entry->mac_addr[2], 0xff & entry->mac_addr[3], - 0xff & entry->mac_addr[4], 0xff & entry->mac_addr[5]); + unsigned short place; + struct lec_arp_table *tmp; + + place = HASH(to_add->mac_addr[ETH_ALEN-1]); + tmp = priv->lec_arp_tables[place]; + to_add->next = NULL; + if (tmp == NULL) + priv->lec_arp_tables[place] = to_add; + + else { /* add to the end */ + while (tmp->next) + tmp = tmp->next; + tmp->next = to_add; + } + + DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + 0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1], + 0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3], + 0xff&to_add->mac_addr[4], 0xff&to_add->mac_addr[5]); } /* * Remove entry from lec_arp_table */ -static int -lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove) +static int +lec_arp_remove(struct lec_priv *priv, + struct lec_arp_table *to_remove) { - struct hlist_node *node; - struct lec_arp_table *entry; - int i, remove_vcc = 1; - - if (!to_remove) { - return -1; - } - - hlist_del(&to_remove->next); - del_timer(&to_remove->timer); - - /* If this is the only MAC connected to this VCC, also tear down the VCC */ - if (to_remove->status >= ESI_FLUSH_PENDING) { - /* - * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT - */ - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) { - if (memcmp(to_remove->atm_addr, - entry->atm_addr, ATM_ESA_LEN) == 0) { - remove_vcc = 0; - break; - } - } - } - if (remove_vcc) - lec_arp_clear_vccs(to_remove); - } - skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */ - - DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - 0xff & to_remove->mac_addr[0], 0xff & to_remove->mac_addr[1], - 0xff & to_remove->mac_addr[2], 0xff & to_remove->mac_addr[3], - 0xff & to_remove->mac_addr[4], 0xff & to_remove->mac_addr[5]); - return 0; + unsigned short place; + struct lec_arp_table *tmp; + int remove_vcc=1; + + if (!to_remove) { + return -1; + } + place = HASH(to_remove->mac_addr[ETH_ALEN-1]); + tmp = priv->lec_arp_tables[place]; + if (tmp == to_remove) { + priv->lec_arp_tables[place] = tmp->next; + } else { + while(tmp && tmp->next != to_remove) { + tmp = tmp->next; + } + if (!tmp) {/* Entry was not found */ + return -1; + } + } + tmp->next = to_remove->next; + del_timer(&to_remove->timer); + + /* If this is the only MAC connected to this VCC, also tear down + the VCC */ + if (to_remove->status >= ESI_FLUSH_PENDING) { + /* + * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT + */ + for(place = 0; place < LEC_ARP_TABLE_SIZE; place++) { + for(tmp = priv->lec_arp_tables[place]; tmp != NULL; tmp = tmp->next) { + if (memcmp(tmp->atm_addr, to_remove->atm_addr, + ATM_ESA_LEN)==0) { + remove_vcc=0; + break; + } + } + } + if (remove_vcc) + lec_arp_clear_vccs(to_remove); + } + skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */ + + DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1], + 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3], + 0xff&to_remove->mac_addr[4], 0xff&to_remove->mac_addr[5]); + return 0; } #if DEBUG_ARP_TABLE -static char *get_status_string(unsigned char st) +static char* +get_status_string(unsigned char st) { - switch (st) { - case ESI_UNKNOWN: - return "ESI_UNKNOWN"; - case ESI_ARP_PENDING: - return "ESI_ARP_PENDING"; - case ESI_VC_PENDING: - return "ESI_VC_PENDING"; - case ESI_FLUSH_PENDING: - return "ESI_FLUSH_PENDING"; - case ESI_FORWARD_DIRECT: - return "ESI_FORWARD_DIRECT"; - default: - return ""; - } + switch(st) { + case ESI_UNKNOWN: + return "ESI_UNKNOWN"; + case ESI_ARP_PENDING: + return "ESI_ARP_PENDING"; + case ESI_VC_PENDING: + return "ESI_VC_PENDING"; + case ESI_FLUSH_PENDING: + return "ESI_FLUSH_PENDING"; + case ESI_FORWARD_DIRECT: + return "ESI_FORWARD_DIRECT"; + default: + return ""; + } } +#endif -static void dump_arp_table(struct lec_priv *priv) +static void +dump_arp_table(struct lec_priv *priv) { - struct hlist_node *node; - struct lec_arp_table *rulla; - char buf[256]; - int i, j, offset; - - printk("Dump %p:\n", priv); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry(rulla, node, &priv->lec_arp_tables[i], next) { - offset = 0; - offset += sprintf(buf, "%d: %p\n", i, rulla); - offset += sprintf(buf + offset, "Mac:"); - for (j = 0; j < ETH_ALEN; j++) { - offset += sprintf(buf + offset, - "%2.2x ", - rulla->mac_addr[j] & 0xff); - } - offset += sprintf(buf + offset, "Atm:"); - for (j = 0; j < ATM_ESA_LEN; j++) { - offset += sprintf(buf + offset, - "%2.2x ", - rulla->atm_addr[j] & 0xff); - } - offset += sprintf(buf + offset, - "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", - rulla->vcc ? rulla->vcc->vpi : 0, - rulla->vcc ? rulla->vcc->vci : 0, - rulla->recv_vcc ? rulla->recv_vcc-> - vpi : 0, - rulla->recv_vcc ? rulla->recv_vcc-> - vci : 0, rulla->last_used, - rulla->timestamp, rulla->no_tries); - offset += - sprintf(buf + offset, - "Flags:%x, Packets_flooded:%x, Status: %s ", - rulla->flags, rulla->packets_flooded, - get_status_string(rulla->status)); - printk("%s\n", buf); - } - } - - if (!hlist_empty(&priv->lec_no_forward)) - printk("No forward\n"); - hlist_for_each_entry(rulla, node, &priv->lec_no_forward, next) { - offset = 0; - offset += sprintf(buf + offset, "Mac:"); - for (j = 0; j < ETH_ALEN; j++) { - offset += sprintf(buf + offset, "%2.2x ", - rulla->mac_addr[j] & 0xff); - } - offset += sprintf(buf + offset, "Atm:"); - for (j = 0; j < ATM_ESA_LEN; j++) { - offset += sprintf(buf + offset, "%2.2x ", - rulla->atm_addr[j] & 0xff); - } - offset += sprintf(buf + offset, - "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", - rulla->vcc ? rulla->vcc->vpi : 0, - rulla->vcc ? rulla->vcc->vci : 0, - rulla->recv_vcc ? rulla->recv_vcc->vpi : 0, - rulla->recv_vcc ? rulla->recv_vcc->vci : 0, - rulla->last_used, - rulla->timestamp, rulla->no_tries); - offset += sprintf(buf + offset, - "Flags:%x, Packets_flooded:%x, Status: %s ", - rulla->flags, rulla->packets_flooded, - get_status_string(rulla->status)); - printk("%s\n", buf); - } - - if (!hlist_empty(&priv->lec_arp_empty_ones)) - printk("Empty ones\n"); - hlist_for_each_entry(rulla, node, &priv->lec_arp_empty_ones, next) { - offset = 0; - offset += sprintf(buf + offset, "Mac:"); - for (j = 0; j < ETH_ALEN; j++) { - offset += sprintf(buf + offset, "%2.2x ", - rulla->mac_addr[j] & 0xff); - } - offset += sprintf(buf + offset, "Atm:"); - for (j = 0; j < ATM_ESA_LEN; j++) { - offset += sprintf(buf + offset, "%2.2x ", - rulla->atm_addr[j] & 0xff); - } - offset += sprintf(buf + offset, - "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", - rulla->vcc ? rulla->vcc->vpi : 0, - rulla->vcc ? rulla->vcc->vci : 0, - rulla->recv_vcc ? rulla->recv_vcc->vpi : 0, - rulla->recv_vcc ? rulla->recv_vcc->vci : 0, - rulla->last_used, - rulla->timestamp, rulla->no_tries); - offset += sprintf(buf + offset, - "Flags:%x, Packets_flooded:%x, Status: %s ", - rulla->flags, rulla->packets_flooded, - get_status_string(rulla->status)); - printk("%s", buf); - } - - if (!hlist_empty(&priv->mcast_fwds)) - printk("Multicast Forward VCCs\n"); - hlist_for_each_entry(rulla, node, &priv->mcast_fwds, next) { - offset = 0; - offset += sprintf(buf + offset, "Mac:"); - for (j = 0; j < ETH_ALEN; j++) { - offset += sprintf(buf + offset, "%2.2x ", - rulla->mac_addr[j] & 0xff); - } - offset += sprintf(buf + offset, "Atm:"); - for (j = 0; j < ATM_ESA_LEN; j++) { - offset += sprintf(buf + offset, "%2.2x ", - rulla->atm_addr[j] & 0xff); - } - offset += sprintf(buf + offset, - "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", - rulla->vcc ? rulla->vcc->vpi : 0, - rulla->vcc ? rulla->vcc->vci : 0, - rulla->recv_vcc ? rulla->recv_vcc->vpi : 0, - rulla->recv_vcc ? rulla->recv_vcc->vci : 0, - rulla->last_used, - rulla->timestamp, rulla->no_tries); - offset += sprintf(buf + offset, - "Flags:%x, Packets_flooded:%x, Status: %s ", - rulla->flags, rulla->packets_flooded, - get_status_string(rulla->status)); - printk("%s\n", buf); - } +#if DEBUG_ARP_TABLE + int i,j, offset; + struct lec_arp_table *rulla; + char buf[1024]; + struct lec_arp_table **lec_arp_tables = + (struct lec_arp_table **)priv->lec_arp_tables; + struct lec_arp_table *lec_arp_empty_ones = + (struct lec_arp_table *)priv->lec_arp_empty_ones; + struct lec_arp_table *lec_no_forward = + (struct lec_arp_table *)priv->lec_no_forward; + struct lec_arp_table *mcast_fwds = priv->mcast_fwds; + + + printk("Dump %p:\n",priv); + for (i=0;imac_addr[j]&0xff); + } + offset +=sprintf(buf+offset,"Atm:"); + for(j=0;jatm_addr[j]&0xff); + } + offset+=sprintf(buf+offset, + "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", + rulla->vcc?rulla->vcc->vpi:0, + rulla->vcc?rulla->vcc->vci:0, + rulla->recv_vcc?rulla->recv_vcc->vpi:0, + rulla->recv_vcc?rulla->recv_vcc->vci:0, + rulla->last_used, + rulla->timestamp, rulla->no_tries); + offset+=sprintf(buf+offset, + "Flags:%x, Packets_flooded:%x, Status: %s ", + rulla->flags, rulla->packets_flooded, + get_status_string(rulla->status)); + offset+=sprintf(buf+offset,"->%p\n",rulla->next); + rulla = rulla->next; + } + printk("%s",buf); + } + rulla = lec_no_forward; + if (rulla) + printk("No forward\n"); + while(rulla) { + offset=0; + offset += sprintf(buf+offset,"Mac:"); + for(j=0;jmac_addr[j]&0xff); + } + offset +=sprintf(buf+offset,"Atm:"); + for(j=0;jatm_addr[j]&0xff); + } + offset+=sprintf(buf+offset, + "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", + rulla->vcc?rulla->vcc->vpi:0, + rulla->vcc?rulla->vcc->vci:0, + rulla->recv_vcc?rulla->recv_vcc->vpi:0, + rulla->recv_vcc?rulla->recv_vcc->vci:0, + rulla->last_used, + rulla->timestamp, rulla->no_tries); + offset+=sprintf(buf+offset, + "Flags:%x, Packets_flooded:%x, Status: %s ", + rulla->flags, rulla->packets_flooded, + get_status_string(rulla->status)); + offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next); + rulla = rulla->next; + printk("%s",buf); + } + rulla = lec_arp_empty_ones; + if (rulla) + printk("Empty ones\n"); + while(rulla) { + offset=0; + offset += sprintf(buf+offset,"Mac:"); + for(j=0;jmac_addr[j]&0xff); + } + offset +=sprintf(buf+offset,"Atm:"); + for(j=0;jatm_addr[j]&0xff); + } + offset+=sprintf(buf+offset, + "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", + rulla->vcc?rulla->vcc->vpi:0, + rulla->vcc?rulla->vcc->vci:0, + rulla->recv_vcc?rulla->recv_vcc->vpi:0, + rulla->recv_vcc?rulla->recv_vcc->vci:0, + rulla->last_used, + rulla->timestamp, rulla->no_tries); + offset+=sprintf(buf+offset, + "Flags:%x, Packets_flooded:%x, Status: %s ", + rulla->flags, rulla->packets_flooded, + get_status_string(rulla->status)); + offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next); + rulla = rulla->next; + printk("%s",buf); + } + + rulla = mcast_fwds; + if (rulla) + printk("Multicast Forward VCCs\n"); + while(rulla) { + offset=0; + offset += sprintf(buf+offset,"Mac:"); + for(j=0;jmac_addr[j]&0xff); + } + offset +=sprintf(buf+offset,"Atm:"); + for(j=0;jatm_addr[j]&0xff); + } + offset+=sprintf(buf+offset, + "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", + rulla->vcc?rulla->vcc->vpi:0, + rulla->vcc?rulla->vcc->vci:0, + rulla->recv_vcc?rulla->recv_vcc->vpi:0, + rulla->recv_vcc?rulla->recv_vcc->vci:0, + rulla->last_used, + rulla->timestamp, rulla->no_tries); + offset+=sprintf(buf+offset, + "Flags:%x, Packets_flooded:%x, Status: %s ", + rulla->flags, rulla->packets_flooded, + get_status_string(rulla->status)); + offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next); + rulla = rulla->next; + printk("%s",buf); + } -} -#else -#define dump_arp_table(priv) do { } while (0) #endif +} /* * Destruction of arp-cache */ -static void lec_arp_destroy(struct lec_priv *priv) +static void +lec_arp_destroy(struct lec_priv *priv) { unsigned long flags; - struct hlist_node *node, *next; - struct lec_arp_table *entry; - int i; - - cancel_rearming_delayed_work(&priv->lec_arp_work); + struct lec_arp_table *entry, *next; + int i; - /* - * Remove all entries - */ + del_timer_sync(&priv->lec_arp_timer); + + /* + * Remove all entries + */ spin_lock_irqsave(&priv->lec_arp_lock, flags); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { - lec_arp_remove(priv, entry); - lec_arp_put(entry); - } - INIT_HLIST_HEAD(&priv->lec_arp_tables[i]); - } - - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) { - del_timer_sync(&entry->timer); - lec_arp_clear_vccs(entry); - hlist_del(&entry->next); - lec_arp_put(entry); - } - INIT_HLIST_HEAD(&priv->lec_arp_empty_ones); - - hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) { - del_timer_sync(&entry->timer); - lec_arp_clear_vccs(entry); - hlist_del(&entry->next); - lec_arp_put(entry); - } - INIT_HLIST_HEAD(&priv->lec_no_forward); - - hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) { - /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ - lec_arp_clear_vccs(entry); - hlist_del(&entry->next); - lec_arp_put(entry); - } - INIT_HLIST_HEAD(&priv->mcast_fwds); - priv->mcast_vcc = NULL; + for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { + for(entry = priv->lec_arp_tables[i]; entry != NULL; entry=next) { + next = entry->next; + lec_arp_remove(priv, entry); + kfree(entry); + } + } + entry = priv->lec_arp_empty_ones; + while(entry) { + next = entry->next; + del_timer_sync(&entry->timer); + lec_arp_clear_vccs(entry); + kfree(entry); + entry = next; + } + priv->lec_arp_empty_ones = NULL; + entry = priv->lec_no_forward; + while(entry) { + next = entry->next; + del_timer_sync(&entry->timer); + lec_arp_clear_vccs(entry); + kfree(entry); + entry = next; + } + priv->lec_no_forward = NULL; + entry = priv->mcast_fwds; + while(entry) { + next = entry->next; + /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ + lec_arp_clear_vccs(entry); + kfree(entry); + entry = next; + } + priv->mcast_fwds = NULL; + priv->mcast_vcc = NULL; + memset(priv->lec_arp_tables, 0, + sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE); spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } + /* * Find entry by mac_address */ -static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, - unsigned char *mac_addr) +static struct lec_arp_table* +lec_arp_find(struct lec_priv *priv, + unsigned char *mac_addr) { - struct hlist_node *node; - struct hlist_head *head; - struct lec_arp_table *entry; - - DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff, - mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff); - - head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])]; - hlist_for_each_entry(entry, node, head, next) { - if (!compare_ether_addr(mac_addr, entry->mac_addr)) { - return entry; - } - } - return NULL; + unsigned short place; + struct lec_arp_table *to_return; + + DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff, + mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff); + place = HASH(mac_addr[ETH_ALEN-1]); + + to_return = priv->lec_arp_tables[place]; + while(to_return) { + if (!compare_ether_addr(mac_addr, to_return->mac_addr)) { + return to_return; + } + to_return = to_return->next; + } + return NULL; } -static struct lec_arp_table *make_entry(struct lec_priv *priv, - unsigned char *mac_addr) +static struct lec_arp_table* +make_entry(struct lec_priv *priv, unsigned char *mac_addr) { - struct lec_arp_table *to_return; - - to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); - if (!to_return) { - printk("LEC: Arp entry kmalloc failed\n"); - return NULL; - } - memcpy(to_return->mac_addr, mac_addr, ETH_ALEN); - INIT_HLIST_NODE(&to_return->next); - init_timer(&to_return->timer); - to_return->timer.function = lec_arp_expire_arp; - to_return->timer.data = (unsigned long)to_return; - to_return->last_used = jiffies; - to_return->priv = priv; - skb_queue_head_init(&to_return->tx_wait); - atomic_set(&to_return->usage, 1); - return to_return; + struct lec_arp_table *to_return; + + to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); + if (!to_return) { + printk("LEC: Arp entry kmalloc failed\n"); + return NULL; + } + memcpy(to_return->mac_addr, mac_addr, ETH_ALEN); + init_timer(&to_return->timer); + to_return->timer.function = lec_arp_expire_arp; + to_return->timer.data = (unsigned long) to_return; + to_return->last_used = jiffies; + to_return->priv = priv; + skb_queue_head_init(&to_return->tx_wait); + return to_return; } -/* Arp sent timer expired */ -static void lec_arp_expire_arp(unsigned long data) +/* + * + * Arp sent timer expired + * + */ +static void +lec_arp_expire_arp(unsigned long data) { - struct lec_arp_table *entry; - - entry = (struct lec_arp_table *)data; - - DPRINTK("lec_arp_expire_arp\n"); - if (entry->status == ESI_ARP_PENDING) { - if (entry->no_tries <= entry->priv->max_retry_count) { - if (entry->is_rdesc) - send_to_lecd(entry->priv, l_rdesc_arp_xmt, - entry->mac_addr, NULL, NULL); - else - send_to_lecd(entry->priv, l_arp_xmt, - entry->mac_addr, NULL, NULL); - entry->no_tries++; - } - mod_timer(&entry->timer, jiffies + (1 * HZ)); - } + struct lec_arp_table *entry; + + entry = (struct lec_arp_table *)data; + + DPRINTK("lec_arp_expire_arp\n"); + if (entry->status == ESI_ARP_PENDING) { + if (entry->no_tries <= entry->priv->max_retry_count) { + if (entry->is_rdesc) + send_to_lecd(entry->priv, l_rdesc_arp_xmt, entry->mac_addr, NULL, NULL); + else + send_to_lecd(entry->priv, l_arp_xmt, entry->mac_addr, NULL, NULL); + entry->no_tries++; + } + mod_timer(&entry->timer, jiffies + (1*HZ)); + } } -/* Unknown/unused vcc expire, remove associated entry */ -static void lec_arp_expire_vcc(unsigned long data) +/* + * + * Unknown/unused vcc expire, remove associated entry + * + */ +static void +lec_arp_expire_vcc(unsigned long data) { unsigned long flags; - struct lec_arp_table *to_remove = (struct lec_arp_table *)data; - struct lec_priv *priv = (struct lec_priv *)to_remove->priv; + struct lec_arp_table *to_remove = (struct lec_arp_table*)data; + struct lec_priv *priv = (struct lec_priv *)to_remove->priv; + struct lec_arp_table *entry = NULL; - del_timer(&to_remove->timer); + del_timer(&to_remove->timer); - DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n", - to_remove, priv, - to_remove->vcc ? to_remove->recv_vcc->vpi : 0, - to_remove->vcc ? to_remove->recv_vcc->vci : 0); + DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n", + to_remove, priv, + to_remove->vcc?to_remove->recv_vcc->vpi:0, + to_remove->vcc?to_remove->recv_vcc->vci:0); + DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward); spin_lock_irqsave(&priv->lec_arp_lock, flags); - hlist_del(&to_remove->next); + if (to_remove == priv->lec_arp_empty_ones) + priv->lec_arp_empty_ones = to_remove->next; + else { + entry = priv->lec_arp_empty_ones; + while (entry && entry->next != to_remove) + entry = entry->next; + if (entry) + entry->next = to_remove->next; + } + if (!entry) { + if (to_remove == priv->lec_no_forward) { + priv->lec_no_forward = to_remove->next; + } else { + entry = priv->lec_no_forward; + while (entry && entry->next != to_remove) + entry = entry->next; + if (entry) + entry->next = to_remove->next; + } + } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - lec_arp_clear_vccs(to_remove); - lec_arp_put(to_remove); + lec_arp_clear_vccs(to_remove); + kfree(to_remove); } /* @@ -1879,171 +1915,158 @@ static void lec_arp_expire_vcc(unsigned long data) * to ESI_FORWARD_DIRECT. This causes the flush period to end * regardless of the progress of the flush protocol. */ -static void lec_arp_check_expire(void *data) +static void +lec_arp_check_expire(unsigned long data) { unsigned long flags; - struct lec_priv *priv = data; - struct hlist_node *node, *next; - struct lec_arp_table *entry; - unsigned long now; - unsigned long time_to_check; - int i; - - DPRINTK("lec_arp_check_expire %p\n", priv); + struct lec_priv *priv = (struct lec_priv *)data; + struct lec_arp_table *entry, *next; + unsigned long now; + unsigned long time_to_check; + int i; + + DPRINTK("lec_arp_check_expire %p\n",priv); + DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones, + priv->lec_no_forward); now = jiffies; -restart: spin_lock_irqsave(&priv->lec_arp_lock, flags); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { - if ((entry->flags) & LEC_REMOTE_FLAG && + for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { + for(entry = priv->lec_arp_tables[i]; entry != NULL; ) { + if ((entry->flags) & LEC_REMOTE_FLAG && priv->topology_change) time_to_check = priv->forward_delay_time; else time_to_check = priv->aging_time; DPRINTK("About to expire: %lx - %lx > %lx\n", - now, entry->last_used, time_to_check); - if (time_after(now, entry->last_used + time_to_check) - && !(entry->flags & LEC_PERMANENT_FLAG) - && !(entry->mac_addr[0] & 0x01)) { /* LANE2: 7.1.20 */ + now,entry->last_used, time_to_check); + if( time_after(now, entry->last_used+ + time_to_check) && + !(entry->flags & LEC_PERMANENT_FLAG) && + !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */ /* Remove entry */ DPRINTK("LEC:Entry timed out\n"); + next = entry->next; lec_arp_remove(priv, entry); - lec_arp_put(entry); + kfree(entry); + entry = next; } else { /* Something else */ if ((entry->status == ESI_VC_PENDING || - entry->status == ESI_ARP_PENDING) + entry->status == ESI_ARP_PENDING) && time_after_eq(now, - entry->timestamp + - priv-> - max_unknown_frame_time)) { + entry->timestamp + + priv->max_unknown_frame_time)) { entry->timestamp = jiffies; entry->packets_flooded = 0; if (entry->status == ESI_VC_PENDING) - send_to_lecd(priv, l_svc_setup, - entry->mac_addr, - entry->atm_addr, - NULL); + send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL); } - if (entry->status == ESI_FLUSH_PENDING - && - time_after_eq(now, entry->timestamp + - priv->path_switching_delay)) { + if (entry->status == ESI_FLUSH_PENDING + && + time_after_eq(now, entry->timestamp+ + priv->path_switching_delay)) { struct sk_buff *skb; - struct atm_vcc *vcc = entry->vcc; - lec_arp_hold(entry); - spin_unlock_irqrestore(&priv->lec_arp_lock, flags); while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) - lec_send(vcc, skb, entry->priv); + lec_send(entry->vcc, skb, entry->priv); entry->last_used = jiffies; - entry->status = ESI_FORWARD_DIRECT; - lec_arp_put(entry); - goto restart; + entry->status = + ESI_FORWARD_DIRECT; } + entry = entry->next; } } } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL); + mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL); } - /* * Try to find vcc where mac_address is attached. * */ -static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, - unsigned char *mac_to_find, int is_rdesc, - struct lec_arp_table **ret_entry) +static struct atm_vcc* +lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, + int is_rdesc, struct lec_arp_table **ret_entry) { unsigned long flags; - struct lec_arp_table *entry; + struct lec_arp_table *entry; struct atm_vcc *found; - if (mac_to_find[0] & 0x01) { - switch (priv->lane_version) { - case 1: - return priv->mcast_vcc; - break; - case 2: /* LANE2 wants arp for multicast addresses */ - if (!compare_ether_addr(mac_to_find, bus_mac)) - return priv->mcast_vcc; - break; - default: - break; - } - } + if (mac_to_find[0] & 0x01) { + switch (priv->lane_version) { + case 1: + return priv->mcast_vcc; + break; + case 2: /* LANE2 wants arp for multicast addresses */ + if (!compare_ether_addr(mac_to_find, bus_mac)) + return priv->mcast_vcc; + break; + default: + break; + } + } spin_lock_irqsave(&priv->lec_arp_lock, flags); - entry = lec_arp_find(priv, mac_to_find); - - if (entry) { - if (entry->status == ESI_FORWARD_DIRECT) { - /* Connection Ok */ - entry->last_used = jiffies; - lec_arp_hold(entry); - *ret_entry = entry; - found = entry->vcc; + entry = lec_arp_find(priv, mac_to_find); + + if (entry) { + if (entry->status == ESI_FORWARD_DIRECT) { + /* Connection Ok */ + entry->last_used = jiffies; + *ret_entry = entry; + found = entry->vcc; goto out; - } - /* - * If the LE_ARP cache entry is still pending, reset count to 0 + } + /* If the LE_ARP cache entry is still pending, reset count to 0 * so another LE_ARP request can be made for this frame. */ if (entry->status == ESI_ARP_PENDING) { entry->no_tries = 0; } - /* - * Data direct VC not yet set up, check to see if the unknown - * frame count is greater than the limit. If the limit has - * not been reached, allow the caller to send packet to - * BUS. - */ - if (entry->status != ESI_FLUSH_PENDING && - entry->packets_flooded < - priv->maximum_unknown_frame_count) { - entry->packets_flooded++; - DPRINTK("LEC_ARP: Flooding..\n"); - found = priv->mcast_vcc; + /* Data direct VC not yet set up, check to see if the unknown + frame count is greater than the limit. If the limit has + not been reached, allow the caller to send packet to + BUS. */ + if (entry->status != ESI_FLUSH_PENDING && + entry->packets_floodedmaximum_unknown_frame_count) { + entry->packets_flooded++; + DPRINTK("LEC_ARP: Flooding..\n"); + found = priv->mcast_vcc; goto out; - } - /* - * We got here because entry->status == ESI_FLUSH_PENDING + } + /* We got here because entry->status == ESI_FLUSH_PENDING * or BUS flood limit was reached for an entry which is * in ESI_ARP_PENDING or ESI_VC_PENDING state. */ - lec_arp_hold(entry); - *ret_entry = entry; - DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, - entry->vcc); - found = NULL; - } else { - /* No matching entry was found */ - entry = make_entry(priv, mac_to_find); - DPRINTK("LEC_ARP: Making entry\n"); - if (!entry) { - found = priv->mcast_vcc; + *ret_entry = entry; + DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, entry->vcc); + found = NULL; + } else { + /* No matching entry was found */ + entry = make_entry(priv, mac_to_find); + DPRINTK("LEC_ARP: Making entry\n"); + if (!entry) { + found = priv->mcast_vcc; goto out; - } - lec_arp_add(priv, entry); - /* We want arp-request(s) to be sent */ - entry->packets_flooded = 1; - entry->status = ESI_ARP_PENDING; - entry->no_tries = 1; - entry->last_used = entry->timestamp = jiffies; - entry->is_rdesc = is_rdesc; - if (entry->is_rdesc) - send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, - NULL); - else - send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL); - entry->timer.expires = jiffies + (1 * HZ); - entry->timer.function = lec_arp_expire_arp; - add_timer(&entry->timer); - found = priv->mcast_vcc; - } + } + lec_arp_add(priv, entry); + /* We want arp-request(s) to be sent */ + entry->packets_flooded =1; + entry->status = ESI_ARP_PENDING; + entry->no_tries = 1; + entry->last_used = entry->timestamp = jiffies; + entry->is_rdesc = is_rdesc; + if (entry->is_rdesc) + send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, NULL); + else + send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL); + entry->timer.expires = jiffies + (1*HZ); + entry->timer.function = lec_arp_expire_arp; + add_timer(&entry->timer); + found = priv->mcast_vcc; + } out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); @@ -2051,30 +2074,30 @@ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, } static int -lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, - unsigned long permanent) +lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, + unsigned long permanent) { unsigned long flags; - struct hlist_node *node, *next; - struct lec_arp_table *entry; - int i; + struct lec_arp_table *entry, *next; + int i; - DPRINTK("lec_addr_delete\n"); + DPRINTK("lec_addr_delete\n"); spin_lock_irqsave(&priv->lec_arp_lock, flags); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { - if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) - && (permanent || - !(entry->flags & LEC_PERMANENT_FLAG))) { + for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { + for(entry = priv->lec_arp_tables[i]; entry != NULL; entry = next) { + next = entry->next; + if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) + && (permanent || + !(entry->flags & LEC_PERMANENT_FLAG))) { lec_arp_remove(priv, entry); - lec_arp_put(entry); - } + kfree(entry); + } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - return 0; - } - } + return 0; + } + } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - return -1; + return -1; } /* @@ -2082,98 +2105,109 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, */ static void lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, - unsigned char *atm_addr, unsigned long remoteflag, - unsigned int targetless_le_arp) + unsigned char *atm_addr, unsigned long remoteflag, + unsigned int targetless_le_arp) { unsigned long flags; - struct hlist_node *node, *next; - struct lec_arp_table *entry, *tmp; - int i; + struct lec_arp_table *entry, *tmp; + int i; - DPRINTK("lec:%s", (targetless_le_arp) ? "targetless " : " "); - DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", - mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], - mac_addr[4], mac_addr[5]); + DPRINTK("lec:%s", (targetless_le_arp) ? "targetless ": " "); + DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", + mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3], + mac_addr[4],mac_addr[5]); spin_lock_irqsave(&priv->lec_arp_lock, flags); - entry = lec_arp_find(priv, mac_addr); - if (entry == NULL && targetless_le_arp) - goto out; /* - * LANE2: ignore targetless LE_ARPs for which - * we have no entry in the cache. 7.1.30 - */ - if (!hlist_empty(&priv->lec_arp_empty_ones)) { - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) { - if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) { - hlist_del(&entry->next); - del_timer(&entry->timer); - tmp = lec_arp_find(priv, mac_addr); - if (tmp) { - del_timer(&tmp->timer); - tmp->status = ESI_FORWARD_DIRECT; - memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN); - tmp->vcc = entry->vcc; - tmp->old_push = entry->old_push; - tmp->last_used = jiffies; - del_timer(&entry->timer); - lec_arp_put(entry); - entry = tmp; - } else { - entry->status = ESI_FORWARD_DIRECT; - memcpy(entry->mac_addr, mac_addr, ETH_ALEN); - entry->last_used = jiffies; - lec_arp_add(priv, entry); - } - if (remoteflag) - entry->flags |= LEC_REMOTE_FLAG; - else - entry->flags &= ~LEC_REMOTE_FLAG; - DPRINTK("After update\n"); - dump_arp_table(priv); - goto out; - } - } - } - - entry = lec_arp_find(priv, mac_addr); - if (!entry) { - entry = make_entry(priv, mac_addr); - if (!entry) + entry = lec_arp_find(priv, mac_addr); + if (entry == NULL && targetless_le_arp) + goto out; /* LANE2: ignore targetless LE_ARPs for which + * we have no entry in the cache. 7.1.30 + */ + if (priv->lec_arp_empty_ones) { + entry = priv->lec_arp_empty_ones; + if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) { + priv->lec_arp_empty_ones = entry->next; + } else { + while(entry->next && memcmp(entry->next->atm_addr, + atm_addr, ATM_ESA_LEN)) + entry = entry->next; + if (entry->next) { + tmp = entry; + entry = entry->next; + tmp->next = entry->next; + } else + entry = NULL; + + } + if (entry) { + del_timer(&entry->timer); + tmp = lec_arp_find(priv, mac_addr); + if (tmp) { + del_timer(&tmp->timer); + tmp->status = ESI_FORWARD_DIRECT; + memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN); + tmp->vcc = entry->vcc; + tmp->old_push = entry->old_push; + tmp->last_used = jiffies; + del_timer(&entry->timer); + kfree(entry); + entry=tmp; + } else { + entry->status = ESI_FORWARD_DIRECT; + memcpy(entry->mac_addr, mac_addr, ETH_ALEN); + entry->last_used = jiffies; + lec_arp_add(priv, entry); + } + if (remoteflag) + entry->flags|=LEC_REMOTE_FLAG; + else + entry->flags&=~LEC_REMOTE_FLAG; + DPRINTK("After update\n"); + dump_arp_table(priv); + goto out; + } + } + entry = lec_arp_find(priv, mac_addr); + if (!entry) { + entry = make_entry(priv, mac_addr); + if (!entry) goto out; - entry->status = ESI_UNKNOWN; - lec_arp_add(priv, entry); - /* Temporary, changes before end of function */ - } - memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN); - del_timer(&entry->timer); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry(tmp, node, &priv->lec_arp_tables[i], next) { - if (entry != tmp && - !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) { - /* Vcc to this host exists */ - if (tmp->status > ESI_VC_PENDING) { - /* - * ESI_FLUSH_PENDING, - * ESI_FORWARD_DIRECT - */ - entry->vcc = tmp->vcc; - entry->old_push = tmp->old_push; - } - entry->status = tmp->status; - break; - } - } - } - if (remoteflag) - entry->flags |= LEC_REMOTE_FLAG; - else - entry->flags &= ~LEC_REMOTE_FLAG; - if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) { - entry->status = ESI_VC_PENDING; - send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL); - } - DPRINTK("After update2\n"); - dump_arp_table(priv); + entry->status = ESI_UNKNOWN; + lec_arp_add(priv, entry); + /* Temporary, changes before end of function */ + } + memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN); + del_timer(&entry->timer); + for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { + for(tmp = priv->lec_arp_tables[i]; tmp; tmp=tmp->next) { + if (entry != tmp && + !memcmp(tmp->atm_addr, atm_addr, + ATM_ESA_LEN)) { + /* Vcc to this host exists */ + if (tmp->status > ESI_VC_PENDING) { + /* + * ESI_FLUSH_PENDING, + * ESI_FORWARD_DIRECT + */ + entry->vcc = tmp->vcc; + entry->old_push=tmp->old_push; + } + entry->status=tmp->status; + break; + } + } + } + if (remoteflag) + entry->flags|=LEC_REMOTE_FLAG; + else + entry->flags&=~LEC_REMOTE_FLAG; + if (entry->status == ESI_ARP_PENDING || + entry->status == ESI_UNKNOWN) { + entry->status = ESI_VC_PENDING; + send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL); + } + DPRINTK("After update2\n"); + dump_arp_table(priv); out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } @@ -2183,299 +2217,299 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, */ static void lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, - struct atm_vcc *vcc, - void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb)) + struct atm_vcc *vcc, + void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb)) { unsigned long flags; - struct hlist_node *node; - struct lec_arp_table *entry; - int i, found_entry = 0; + struct lec_arp_table *entry; + int i, found_entry=0; spin_lock_irqsave(&priv->lec_arp_lock, flags); - if (ioc_data->receive == 2) { - /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */ + if (ioc_data->receive == 2) { + /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */ - DPRINTK("LEC_ARP: Attaching mcast forward\n"); + DPRINTK("LEC_ARP: Attaching mcast forward\n"); #if 0 - entry = lec_arp_find(priv, bus_mac); - if (!entry) { - printk("LEC_ARP: Multicast entry not found!\n"); + entry = lec_arp_find(priv, bus_mac); + if (!entry) { + printk("LEC_ARP: Multicast entry not found!\n"); goto out; - } - memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); - entry->recv_vcc = vcc; - entry->old_recv_push = old_push; + } + memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); + entry->recv_vcc = vcc; + entry->old_recv_push = old_push; #endif - entry = make_entry(priv, bus_mac); - if (entry == NULL) + entry = make_entry(priv, bus_mac); + if (entry == NULL) goto out; - del_timer(&entry->timer); - memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); - entry->recv_vcc = vcc; - entry->old_recv_push = old_push; - hlist_add_head(&entry->next, &priv->mcast_fwds); - goto out; - } else if (ioc_data->receive == 1) { - /* - * Vcc which we don't want to make default vcc, - * attach it anyway. - */ - DPRINTK - ("LEC_ARP:Attaching data direct, not default: " - "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", - ioc_data->atm_addr[0], ioc_data->atm_addr[1], - ioc_data->atm_addr[2], ioc_data->atm_addr[3], - ioc_data->atm_addr[4], ioc_data->atm_addr[5], - ioc_data->atm_addr[6], ioc_data->atm_addr[7], - ioc_data->atm_addr[8], ioc_data->atm_addr[9], - ioc_data->atm_addr[10], ioc_data->atm_addr[11], - ioc_data->atm_addr[12], ioc_data->atm_addr[13], - ioc_data->atm_addr[14], ioc_data->atm_addr[15], - ioc_data->atm_addr[16], ioc_data->atm_addr[17], - ioc_data->atm_addr[18], ioc_data->atm_addr[19]); - entry = make_entry(priv, bus_mac); - if (entry == NULL) + del_timer(&entry->timer); + memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); + entry->recv_vcc = vcc; + entry->old_recv_push = old_push; + entry->next = priv->mcast_fwds; + priv->mcast_fwds = entry; + goto out; + } else if (ioc_data->receive == 1) { + /* Vcc which we don't want to make default vcc, attach it + anyway. */ + DPRINTK("LEC_ARP:Attaching data direct, not default :%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", + ioc_data->atm_addr[0],ioc_data->atm_addr[1], + ioc_data->atm_addr[2],ioc_data->atm_addr[3], + ioc_data->atm_addr[4],ioc_data->atm_addr[5], + ioc_data->atm_addr[6],ioc_data->atm_addr[7], + ioc_data->atm_addr[8],ioc_data->atm_addr[9], + ioc_data->atm_addr[10],ioc_data->atm_addr[11], + ioc_data->atm_addr[12],ioc_data->atm_addr[13], + ioc_data->atm_addr[14],ioc_data->atm_addr[15], + ioc_data->atm_addr[16],ioc_data->atm_addr[17], + ioc_data->atm_addr[18],ioc_data->atm_addr[19]); + entry = make_entry(priv, bus_mac); + if (entry == NULL) goto out; - memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); - memset(entry->mac_addr, 0, ETH_ALEN); - entry->recv_vcc = vcc; - entry->old_recv_push = old_push; - entry->status = ESI_UNKNOWN; - entry->timer.expires = jiffies + priv->vcc_timeout_period; - entry->timer.function = lec_arp_expire_vcc; - hlist_add_head(&entry->next, &priv->lec_no_forward); - add_timer(&entry->timer); + memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); + memset(entry->mac_addr, 0, ETH_ALEN); + entry->recv_vcc = vcc; + entry->old_recv_push = old_push; + entry->status = ESI_UNKNOWN; + entry->timer.expires = jiffies + priv->vcc_timeout_period; + entry->timer.function = lec_arp_expire_vcc; + add_timer(&entry->timer); + entry->next = priv->lec_no_forward; + priv->lec_no_forward = entry; dump_arp_table(priv); goto out; - } - DPRINTK - ("LEC_ARP:Attaching data direct, default: " - "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", - ioc_data->atm_addr[0], ioc_data->atm_addr[1], - ioc_data->atm_addr[2], ioc_data->atm_addr[3], - ioc_data->atm_addr[4], ioc_data->atm_addr[5], - ioc_data->atm_addr[6], ioc_data->atm_addr[7], - ioc_data->atm_addr[8], ioc_data->atm_addr[9], - ioc_data->atm_addr[10], ioc_data->atm_addr[11], - ioc_data->atm_addr[12], ioc_data->atm_addr[13], - ioc_data->atm_addr[14], ioc_data->atm_addr[15], - ioc_data->atm_addr[16], ioc_data->atm_addr[17], - ioc_data->atm_addr[18], ioc_data->atm_addr[19]); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) { - if (memcmp - (ioc_data->atm_addr, entry->atm_addr, - ATM_ESA_LEN) == 0) { - DPRINTK("LEC_ARP: Attaching data direct\n"); - DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n", - entry->vcc ? entry->vcc->vci : 0, - entry->recv_vcc ? entry->recv_vcc-> - vci : 0); - found_entry = 1; - del_timer(&entry->timer); - entry->vcc = vcc; - entry->old_push = old_push; - if (entry->status == ESI_VC_PENDING) { - if (priv->maximum_unknown_frame_count - == 0) - entry->status = - ESI_FORWARD_DIRECT; - else { - entry->timestamp = jiffies; - entry->status = - ESI_FLUSH_PENDING; + } + DPRINTK("LEC_ARP:Attaching data direct, default:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", + ioc_data->atm_addr[0],ioc_data->atm_addr[1], + ioc_data->atm_addr[2],ioc_data->atm_addr[3], + ioc_data->atm_addr[4],ioc_data->atm_addr[5], + ioc_data->atm_addr[6],ioc_data->atm_addr[7], + ioc_data->atm_addr[8],ioc_data->atm_addr[9], + ioc_data->atm_addr[10],ioc_data->atm_addr[11], + ioc_data->atm_addr[12],ioc_data->atm_addr[13], + ioc_data->atm_addr[14],ioc_data->atm_addr[15], + ioc_data->atm_addr[16],ioc_data->atm_addr[17], + ioc_data->atm_addr[18],ioc_data->atm_addr[19]); + for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { + for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) { + if (memcmp(ioc_data->atm_addr, entry->atm_addr, + ATM_ESA_LEN)==0) { + DPRINTK("LEC_ARP: Attaching data direct\n"); + DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n", + entry->vcc?entry->vcc->vci:0, + entry->recv_vcc?entry->recv_vcc->vci:0); + found_entry=1; + del_timer(&entry->timer); + entry->vcc = vcc; + entry->old_push = old_push; + if (entry->status == ESI_VC_PENDING) { + if(priv->maximum_unknown_frame_count + ==0) + entry->status = + ESI_FORWARD_DIRECT; + else { + entry->timestamp = jiffies; + entry->status = + ESI_FLUSH_PENDING; #if 0 - send_to_lecd(priv, l_flush_xmt, - NULL, - entry->atm_addr, - NULL); + send_to_lecd(priv,l_flush_xmt, + NULL, + entry->atm_addr, + NULL); #endif - } - } else { - /* - * They were forming a connection - * to us, and we to them. Our - * ATM address is numerically lower - * than theirs, so we make connection - * we formed into default VCC (8.1.11). - * Connection they made gets torn - * down. This might confuse some - * clients. Can be changed if - * someone reports trouble... - */ - ; - } - } - } - } - if (found_entry) { - DPRINTK("After vcc was added\n"); - dump_arp_table(priv); + } + } else { + /* They were forming a connection + to us, and we to them. Our + ATM address is numerically lower + than theirs, so we make connection + we formed into default VCC (8.1.11). + Connection they made gets torn + down. This might confuse some + clients. Can be changed if + someone reports trouble... */ + ; + } + } + } + } + if (found_entry) { + DPRINTK("After vcc was added\n"); + dump_arp_table(priv); goto out; - } - /* - * Not found, snatch address from first data packet that arrives - * from this vcc - */ - entry = make_entry(priv, bus_mac); - if (!entry) + } + /* Not found, snatch address from first data packet that arrives from + this vcc */ + entry = make_entry(priv, bus_mac); + if (!entry) goto out; - entry->vcc = vcc; - entry->old_push = old_push; - memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); - memset(entry->mac_addr, 0, ETH_ALEN); - entry->status = ESI_UNKNOWN; - hlist_add_head(&entry->next, &priv->lec_arp_empty_ones); - entry->timer.expires = jiffies + priv->vcc_timeout_period; - entry->timer.function = lec_arp_expire_vcc; - add_timer(&entry->timer); - DPRINTK("After vcc was added\n"); + entry->vcc = vcc; + entry->old_push = old_push; + memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); + memset(entry->mac_addr, 0, ETH_ALEN); + entry->status = ESI_UNKNOWN; + entry->next = priv->lec_arp_empty_ones; + priv->lec_arp_empty_ones = entry; + entry->timer.expires = jiffies + priv->vcc_timeout_period; + entry->timer.function = lec_arp_expire_vcc; + add_timer(&entry->timer); + DPRINTK("After vcc was added\n"); dump_arp_table(priv); out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } -static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) +static void +lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) { unsigned long flags; - struct hlist_node *node; - struct lec_arp_table *entry; - int i; - - DPRINTK("LEC:lec_flush_complete %lx\n", tran_id); -restart: + struct lec_arp_table *entry; + int i; + + DPRINTK("LEC:lec_flush_complete %lx\n",tran_id); spin_lock_irqsave(&priv->lec_arp_lock, flags); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) { - if (entry->flush_tran_id == tran_id - && entry->status == ESI_FLUSH_PENDING) { - struct sk_buff *skb; - struct atm_vcc *vcc = entry->vcc; - - lec_arp_hold(entry); - spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) - lec_send(vcc, skb, entry->priv); - entry->last_used = jiffies; - entry->status = ESI_FORWARD_DIRECT; - lec_arp_put(entry); - DPRINTK("LEC_ARP: Flushed\n"); - goto restart; - } - } - } + for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { + for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) { + if (entry->flush_tran_id == tran_id && + entry->status == ESI_FLUSH_PENDING) { + struct sk_buff *skb; + + while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) + lec_send(entry->vcc, skb, entry->priv); + entry->status = ESI_FORWARD_DIRECT; + DPRINTK("LEC_ARP: Flushed\n"); + } + } + } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - dump_arp_table(priv); + dump_arp_table(priv); } static void lec_set_flush_tran_id(struct lec_priv *priv, - unsigned char *atm_addr, unsigned long tran_id) + unsigned char *atm_addr, unsigned long tran_id) { unsigned long flags; - struct hlist_node *node; - struct lec_arp_table *entry; - int i; + struct lec_arp_table *entry; + int i; spin_lock_irqsave(&priv->lec_arp_lock, flags); - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) - hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) { - if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) { - entry->flush_tran_id = tran_id; - DPRINTK("Set flush transaction id to %lx for %p\n", - tran_id, entry); - } - } + for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) + for(entry = priv->lec_arp_tables[i]; entry; entry=entry->next) + if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) { + entry->flush_tran_id = tran_id; + DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry); + } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } -static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) +static int +lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) { unsigned long flags; - unsigned char mac_addr[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - struct lec_arp_table *to_add; + unsigned char mac_addr[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + struct lec_arp_table *to_add; struct lec_vcc_priv *vpriv; int err = 0; - + if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL))) return -ENOMEM; vpriv->xoff = 0; vpriv->old_pop = vcc->pop; vcc->user_back = vpriv; - vcc->pop = lec_pop; + vcc->pop = lec_pop; spin_lock_irqsave(&priv->lec_arp_lock, flags); - to_add = make_entry(priv, mac_addr); - if (!to_add) { + to_add = make_entry(priv, mac_addr); + if (!to_add) { vcc->pop = vpriv->old_pop; kfree(vpriv); - err = -ENOMEM; + err = -ENOMEM; goto out; - } - memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN); - to_add->status = ESI_FORWARD_DIRECT; - to_add->flags |= LEC_PERMANENT_FLAG; - to_add->vcc = vcc; - to_add->old_push = vcc->push; - vcc->push = lec_push; - priv->mcast_vcc = vcc; - lec_arp_add(priv, to_add); + } + memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN); + to_add->status = ESI_FORWARD_DIRECT; + to_add->flags |= LEC_PERMANENT_FLAG; + to_add->vcc = vcc; + to_add->old_push = vcc->push; + vcc->push = lec_push; + priv->mcast_vcc = vcc; + lec_arp_add(priv, to_add); out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); - return err; + return err; } -static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) +static void +lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) { unsigned long flags; - struct hlist_node *node, *next; - struct lec_arp_table *entry; - int i; - - DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci); - dump_arp_table(priv); + struct lec_arp_table *entry, *next; + int i; + DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci); + dump_arp_table(priv); spin_lock_irqsave(&priv->lec_arp_lock, flags); - - for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { - if (vcc == entry->vcc) { - lec_arp_remove(priv, entry); - lec_arp_put(entry); - if (priv->mcast_vcc == vcc) { - priv->mcast_vcc = NULL; - } - } - } - } - - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) { - if (entry->vcc == vcc) { - lec_arp_clear_vccs(entry); - del_timer(&entry->timer); - hlist_del(&entry->next); - lec_arp_put(entry); - } - } - - hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) { - if (entry->recv_vcc == vcc) { - lec_arp_clear_vccs(entry); - del_timer(&entry->timer); - hlist_del(&entry->next); - lec_arp_put(entry); - } - } - - hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) { - if (entry->recv_vcc == vcc) { - lec_arp_clear_vccs(entry); - /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ - hlist_del(&entry->next); - lec_arp_put(entry); - } - } + for(i=0;ilec_arp_tables[i];entry; entry=next) { + next = entry->next; + if (vcc == entry->vcc) { + lec_arp_remove(priv, entry); + kfree(entry); + if (priv->mcast_vcc == vcc) { + priv->mcast_vcc = NULL; + } + } + } + } + + entry = priv->lec_arp_empty_ones; + priv->lec_arp_empty_ones = NULL; + while (entry != NULL) { + next = entry->next; + if (entry->vcc == vcc) { /* leave it out from the list */ + lec_arp_clear_vccs(entry); + del_timer(&entry->timer); + kfree(entry); + } + else { /* put it back to the list */ + entry->next = priv->lec_arp_empty_ones; + priv->lec_arp_empty_ones = entry; + } + entry = next; + } + + entry = priv->lec_no_forward; + priv->lec_no_forward = NULL; + while (entry != NULL) { + next = entry->next; + if (entry->recv_vcc == vcc) { + lec_arp_clear_vccs(entry); + del_timer(&entry->timer); + kfree(entry); + } + else { + entry->next = priv->lec_no_forward; + priv->lec_no_forward = entry; + } + entry = next; + } + + entry = priv->mcast_fwds; + priv->mcast_fwds = NULL; + while (entry != NULL) { + next = entry->next; + if (entry->recv_vcc == vcc) { + lec_arp_clear_vccs(entry); + /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ + kfree(entry); + } + else { + entry->next = priv->mcast_fwds; + priv->mcast_fwds = entry; + } + entry = next; + } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); dump_arp_table(priv); @@ -2483,42 +2517,57 @@ static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) static void lec_arp_check_empties(struct lec_priv *priv, - struct atm_vcc *vcc, struct sk_buff *skb) + struct atm_vcc *vcc, struct sk_buff *skb) { - unsigned long flags; - struct hlist_node *node, *next; - struct lec_arp_table *entry, *tmp; - struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; - unsigned char *src; + unsigned long flags; + struct lec_arp_table *entry, *prev; + struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; + unsigned char *src; #ifdef CONFIG_TR - struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data; + struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data; - if (priv->is_trdev) - src = tr_hdr->h_source; - else + if (priv->is_trdev) src = tr_hdr->h_source; + else #endif - src = hdr->h_source; + src = hdr->h_source; spin_lock_irqsave(&priv->lec_arp_lock, flags); - hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) { - if (vcc == entry->vcc) { - del_timer(&entry->timer); - memcpy(entry->mac_addr, src, ETH_ALEN); - entry->status = ESI_FORWARD_DIRECT; - entry->last_used = jiffies; - /* We might have got an entry */ - if ((tmp = lec_arp_find(priv, src))) { - lec_arp_remove(priv, tmp); - lec_arp_put(tmp); - } - hlist_del(&entry->next); - lec_arp_add(priv, entry); - goto out; - } - } - DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n"); + entry = priv->lec_arp_empty_ones; + if (vcc == entry->vcc) { + del_timer(&entry->timer); + memcpy(entry->mac_addr, src, ETH_ALEN); + entry->status = ESI_FORWARD_DIRECT; + entry->last_used = jiffies; + priv->lec_arp_empty_ones = entry->next; + /* We might have got an entry */ + if ((prev = lec_arp_find(priv,src))) { + lec_arp_remove(priv, prev); + kfree(prev); + } + lec_arp_add(priv, entry); + goto out; + } + prev = entry; + entry = entry->next; + while (entry && entry->vcc != vcc) { + prev= entry; + entry = entry->next; + } + if (!entry) { + DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n"); + goto out; + } + del_timer(&entry->timer); + memcpy(entry->mac_addr, src, ETH_ALEN); + entry->status = ESI_FORWARD_DIRECT; + entry->last_used = jiffies; + prev->next = entry->next; + if ((prev = lec_arp_find(priv, src))) { + lec_arp_remove(priv, prev); + kfree(prev); + } + lec_arp_add(priv, entry); out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } - MODULE_LICENSE("GPL"); diff --git a/trunk/net/atm/lec.h b/trunk/net/atm/lec.h index 8ac6b7321635..c22a8bfa1f81 100644 --- a/trunk/net/atm/lec.h +++ b/trunk/net/atm/lec.h @@ -1,13 +1,14 @@ /* + * * Lan Emulation client header file * - * Marko Kiiskila + * Marko Kiiskila mkiiskila@yahoo.com + * */ #ifndef _LEC_H_ #define _LEC_H_ -#include #include #include #include @@ -15,18 +16,18 @@ #define LEC_HEADER_LEN 16 struct lecdatahdr_8023 { - unsigned short le_header; - unsigned char h_dest[ETH_ALEN]; - unsigned char h_source[ETH_ALEN]; - unsigned short h_type; + unsigned short le_header; + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + unsigned short h_type; }; struct lecdatahdr_8025 { - unsigned short le_header; - unsigned char ac_pad; - unsigned char fc; - unsigned char h_dest[ETH_ALEN]; - unsigned char h_source[ETH_ALEN]; + unsigned short le_header; + unsigned char ac_pad; + unsigned char fc; + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; }; #define LEC_MINIMUM_8023_SIZE 62 @@ -43,18 +44,17 @@ struct lecdatahdr_8025 { * */ struct lane2_ops { - int (*resolve) (struct net_device *dev, u8 *dst_mac, int force, - u8 **tlvs, u32 *sizeoftlvs); - int (*associate_req) (struct net_device *dev, u8 *lan_dst, - u8 *tlvs, u32 sizeoftlvs); - void (*associate_indicator) (struct net_device *dev, u8 *mac_addr, - u8 *tlvs, u32 sizeoftlvs); + int (*resolve)(struct net_device *dev, u8 *dst_mac, int force, + u8 **tlvs, u32 *sizeoftlvs); + int (*associate_req)(struct net_device *dev, u8 *lan_dst, + u8 *tlvs, u32 sizeoftlvs); + void (*associate_indicator)(struct net_device *dev, u8 *mac_addr, + u8 *tlvs, u32 sizeoftlvs); }; /* * ATM LAN Emulation supports both LLC & Dix Ethernet EtherType * frames. - * * 1. Dix Ethernet EtherType frames encoded by placing EtherType * field in h_type field. Data follows immediatelly after header. * 2. LLC Data frames whose total length, including LLC field and data, @@ -70,88 +70,72 @@ struct lane2_ops { #define LEC_ARP_TABLE_SIZE 16 struct lec_priv { - struct net_device_stats stats; - unsigned short lecid; /* Lecid of this client */ - struct hlist_head lec_arp_empty_ones; - /* Used for storing VCC's that don't have a MAC address attached yet */ - struct hlist_head lec_arp_tables[LEC_ARP_TABLE_SIZE]; - /* Actual LE ARP table */ - struct hlist_head lec_no_forward; - /* - * Used for storing VCC's (and forward packets from) which are to - * age out by not using them to forward packets. - * This is because to some LE clients there will be 2 VCCs. Only - * one of them gets used. - */ - struct hlist_head mcast_fwds; - /* - * With LANEv2 it is possible that BUS (or a special multicast server) - * establishes multiple Multicast Forward VCCs to us. This list - * collects all those VCCs. LANEv1 client has only one item in this - * list. These entries are not aged out. - */ - spinlock_t lec_arp_lock; - struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */ - struct atm_vcc *lecd; - struct work_struct lec_arp_work; /* C10 */ - unsigned int maximum_unknown_frame_count; - /* - * Within the period of time defined by this variable, the client will send - * no more than C10 frames to BUS for a given unicast destination. (C11) - */ - unsigned long max_unknown_frame_time; - /* - * If no traffic has been sent in this vcc for this period of time, - * vcc will be torn down (C12) - */ - unsigned long vcc_timeout_period; - /* - * An LE Client MUST not retry an LE_ARP_REQUEST for a - * given frame's LAN Destination more than maximum retry count times, - * after the first LEC_ARP_REQUEST (C13) - */ - unsigned short max_retry_count; - /* - * Max time the client will maintain an entry in its arp cache in - * absence of a verification of that relationship (C17) - */ - unsigned long aging_time; - /* - * Max time the client will maintain an entry in cache when - * topology change flag is true (C18) - */ - unsigned long forward_delay_time; /* Topology change flag (C19) */ - int topology_change; - /* - * Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE - * cycle to take (C20) - */ - unsigned long arp_response_time; - /* - * Time limit ot wait to receive an LE_FLUSH_RESPONSE after the - * LE_FLUSH_REQUEST has been sent before taking recover action. (C21) - */ - unsigned long flush_timeout; - /* The time since sending a frame to the bus after which the - * LE Client may assume that the frame has been either discarded or - * delivered to the recipient (C22) - */ - unsigned long path_switching_delay; + struct net_device_stats stats; + unsigned short lecid; /* Lecid of this client */ + struct lec_arp_table *lec_arp_empty_ones; + /* Used for storing VCC's that don't have a MAC address attached yet */ + struct lec_arp_table *lec_arp_tables[LEC_ARP_TABLE_SIZE]; + /* Actual LE ARP table */ + struct lec_arp_table *lec_no_forward; + /* Used for storing VCC's (and forward packets from) which are to + age out by not using them to forward packets. + This is because to some LE clients there will be 2 VCCs. Only + one of them gets used. */ + struct lec_arp_table *mcast_fwds; + /* With LANEv2 it is possible that BUS (or a special multicast server) + establishes multiple Multicast Forward VCCs to us. This list + collects all those VCCs. LANEv1 client has only one item in this + list. These entries are not aged out. */ + spinlock_t lec_arp_lock; + struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */ + struct atm_vcc *lecd; + struct timer_list lec_arp_timer; + /* C10 */ + unsigned int maximum_unknown_frame_count; +/* Within the period of time defined by this variable, the client will send + no more than C10 frames to BUS for a given unicast destination. (C11) */ + unsigned long max_unknown_frame_time; +/* If no traffic has been sent in this vcc for this period of time, + vcc will be torn down (C12)*/ + unsigned long vcc_timeout_period; +/* An LE Client MUST not retry an LE_ARP_REQUEST for a + given frame's LAN Destination more than maximum retry count times, + after the first LEC_ARP_REQUEST (C13)*/ + unsigned short max_retry_count; +/* Max time the client will maintain an entry in its arp cache in + absence of a verification of that relationship (C17)*/ + unsigned long aging_time; +/* Max time the client will maintain an entry in cache when + topology change flag is true (C18) */ + unsigned long forward_delay_time; +/* Topology change flag (C19)*/ + int topology_change; +/* Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE + cycle to take (C20)*/ + unsigned long arp_response_time; +/* Time limit ot wait to receive an LE_FLUSH_RESPONSE after the + LE_FLUSH_REQUEST has been sent before taking recover action. (C21)*/ + unsigned long flush_timeout; +/* The time since sending a frame to the bus after which the + LE Client may assume that the frame has been either discarded or + delivered to the recipient (C22) */ + unsigned long path_switching_delay; - u8 *tlvs; /* LANE2: TLVs are new */ - u32 sizeoftlvs; /* The size of the tlv array in bytes */ - int lane_version; /* LANE2 */ - int itfnum; /* e.g. 2 for lec2, 5 for lec5 */ - struct lane2_ops *lane2_ops; /* can be NULL for LANE v1 */ - int is_proxy; /* bridge between ATM and Ethernet */ - int is_trdev; /* Device type, 0 = Ethernet, 1 = TokenRing */ + u8 *tlvs; /* LANE2: TLVs are new */ + u32 sizeoftlvs; /* The size of the tlv array in bytes */ + int lane_version; /* LANE2 */ + int itfnum; /* e.g. 2 for lec2, 5 for lec5 */ + struct lane2_ops *lane2_ops; /* can be NULL for LANE v1 */ + int is_proxy; /* bridge between ATM and Ethernet */ + int is_trdev; /* Device type, 0 = Ethernet, 1 = TokenRing */ }; struct lec_vcc_priv { - void (*old_pop) (struct atm_vcc *vcc, struct sk_buff *skb); + void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); int xoff; }; #define LEC_VCC_PRIV(vcc) ((struct lec_vcc_priv *)((vcc)->user_back)) -#endif /* _LEC_H_ */ +#endif /* _LEC_H_ */ + diff --git a/trunk/net/atm/lec_arpc.h b/trunk/net/atm/lec_arpc.h index ec67435a40a6..397448094648 100644 --- a/trunk/net/atm/lec_arpc.h +++ b/trunk/net/atm/lec_arpc.h @@ -1,96 +1,92 @@ /* * Lec arp cache + * Marko Kiiskila mkiiskila@yahoo.com * - * Marko Kiiskila */ -#ifndef _LEC_ARP_H_ -#define _LEC_ARP_H_ +#ifndef _LEC_ARP_H +#define _LEC_ARP_H #include #include #include #include struct lec_arp_table { - struct hlist_node next; /* Linked entry list */ - unsigned char atm_addr[ATM_ESA_LEN]; /* Atm address */ - unsigned char mac_addr[ETH_ALEN]; /* Mac address */ - int is_rdesc; /* Mac address is a route descriptor */ - struct atm_vcc *vcc; /* Vcc this entry is attached */ - struct atm_vcc *recv_vcc; /* Vcc we receive data from */ + struct lec_arp_table *next; /* Linked entry list */ + unsigned char atm_addr[ATM_ESA_LEN]; /* Atm address */ + unsigned char mac_addr[ETH_ALEN]; /* Mac address */ + int is_rdesc; /* Mac address is a route descriptor */ + struct atm_vcc *vcc; /* Vcc this entry is attached */ + struct atm_vcc *recv_vcc; /* Vcc we receive data from */ + void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); + /* Push that leads to daemon */ + void (*old_recv_push)(struct atm_vcc *vcc, struct sk_buff *skb); + /* Push that leads to daemon */ + void (*old_close)(struct atm_vcc *vcc); + /* We want to see when this + * vcc gets closed */ + unsigned long last_used; /* For expiry */ + unsigned long timestamp; /* Used for various timestamping + * things: + * 1. FLUSH started + * (status=ESI_FLUSH_PENDING) + * 2. Counting to + * max_unknown_frame_time + * (status=ESI_ARP_PENDING|| + * status=ESI_VC_PENDING) + */ + unsigned char no_tries; /* No of times arp retry has been + tried */ + unsigned char status; /* Status of this entry */ + unsigned short flags; /* Flags for this entry */ + unsigned short packets_flooded; /* Data packets flooded */ + unsigned long flush_tran_id; /* Transaction id in flush protocol */ + struct timer_list timer; /* Arping timer */ + struct lec_priv *priv; /* Pointer back */ - void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb); - /* Push that leads to daemon */ - - void (*old_recv_push) (struct atm_vcc *vcc, struct sk_buff *skb); - /* Push that leads to daemon */ - - unsigned long last_used; /* For expiry */ - unsigned long timestamp; /* Used for various timestamping things: - * 1. FLUSH started - * (status=ESI_FLUSH_PENDING) - * 2. Counting to - * max_unknown_frame_time - * (status=ESI_ARP_PENDING|| - * status=ESI_VC_PENDING) - */ - unsigned char no_tries; /* No of times arp retry has been tried */ - unsigned char status; /* Status of this entry */ - unsigned short flags; /* Flags for this entry */ - unsigned short packets_flooded; /* Data packets flooded */ - unsigned long flush_tran_id; /* Transaction id in flush protocol */ - struct timer_list timer; /* Arping timer */ - struct lec_priv *priv; /* Pointer back */ - u8 *tlvs; - u32 sizeoftlvs; /* - * LANE2: Each MAC address can have TLVs - * associated with it. sizeoftlvs tells the - * the length of the tlvs array - */ - struct sk_buff_head tx_wait; /* wait queue for outgoing packets */ - atomic_t usage; /* usage count */ + u8 *tlvs; /* LANE2: Each MAC address can have TLVs */ + u32 sizeoftlvs; /* associated with it. sizeoftlvs tells the */ + /* the length of the tlvs array */ + struct sk_buff_head tx_wait; /* wait queue for outgoing packets */ }; -/* - * LANE2: Template tlv struct for accessing - * the tlvs in the lec_arp_table->tlvs array - */ -struct tlv { - u32 type; - u8 length; - u8 value[255]; +struct tlv { /* LANE2: Template tlv struct for accessing */ + /* the tlvs in the lec_arp_table->tlvs array*/ + u32 type; + u8 length; + u8 value[255]; }; /* Status fields */ -#define ESI_UNKNOWN 0 /* - * Next packet sent to this mac address - * causes ARP-request to be sent - */ -#define ESI_ARP_PENDING 1 /* - * There is no ATM address associated with this - * 48-bit address. The LE-ARP protocol is in - * progress. - */ -#define ESI_VC_PENDING 2 /* - * There is a valid ATM address associated with - * this 48-bit address but there is no VC set - * up to that ATM address. The signaling - * protocol is in process. - */ -#define ESI_FLUSH_PENDING 4 /* - * The LEC has been notified of the FLUSH_START - * status and it is assumed that the flush - * protocol is in process. - */ -#define ESI_FORWARD_DIRECT 5 /* - * Either the Path Switching Delay (C22) has - * elapsed or the LEC has notified the Mapping - * that the flush protocol has completed. In - * either case, it is safe to forward packets - * to this address via the data direct VC. - */ +#define ESI_UNKNOWN 0 /* + * Next packet sent to this mac address + * causes ARP-request to be sent + */ +#define ESI_ARP_PENDING 1 /* + * There is no ATM address associated with this + * 48-bit address. The LE-ARP protocol is in + * progress. + */ +#define ESI_VC_PENDING 2 /* + * There is a valid ATM address associated with + * this 48-bit address but there is no VC set + * up to that ATM address. The signaling + * protocol is in process. + */ +#define ESI_FLUSH_PENDING 4 /* + * The LEC has been notified of the FLUSH_START + * status and it is assumed that the flush + * protocol is in process. + */ +#define ESI_FORWARD_DIRECT 5 /* + * Either the Path Switching Delay (C22) has + * elapsed or the LEC has notified the Mapping + * that the flush protocol has completed. In + * either case, it is safe to forward packets + * to this address via the data direct VC. + */ /* Flag values */ #define LEC_REMOTE_FLAG 0x0001 #define LEC_PERMANENT_FLAG 0x0002 -#endif /* _LEC_ARP_H_ */ +#endif diff --git a/trunk/net/ipv4/cipso_ipv4.c b/trunk/net/ipv4/cipso_ipv4.c index a8e2e879a647..c4e469ff842d 100644 --- a/trunk/net/ipv4/cipso_ipv4.c +++ b/trunk/net/ipv4/cipso_ipv4.c @@ -485,7 +485,7 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) * */ int cipso_v4_doi_remove(u32 doi, - struct netlbl_audit *audit_info, + u32 audit_secid, void (*callback) (struct rcu_head * head)) { struct cipso_v4_doi *doi_def; @@ -506,7 +506,7 @@ int cipso_v4_doi_remove(u32 doi, list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) if (dom_iter->valid) netlbl_domhsh_remove(dom_iter->domain, - audit_info); + audit_secid); cipso_v4_cache_invalidate(); rcu_read_unlock(); diff --git a/trunk/net/netlabel/netlabel_cipso_v4.c b/trunk/net/netlabel/netlabel_cipso_v4.c index a6ce1d6d5c59..09986ca962a6 100644 --- a/trunk/net/netlabel/netlabel_cipso_v4.c +++ b/trunk/net/netlabel/netlabel_cipso_v4.c @@ -384,15 +384,11 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info) u32 doi; const char *type_str = "(unknown)"; struct audit_buffer *audit_buf; - struct netlbl_audit audit_info; if (!info->attrs[NLBL_CIPSOV4_A_DOI] || !info->attrs[NLBL_CIPSOV4_A_MTYPE]) return -EINVAL; - doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); - netlbl_netlink_auditinfo(skb, &audit_info); - type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]); switch (type) { case CIPSO_V4_MAP_STD: @@ -405,14 +401,13 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info) break; } - audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD, - &audit_info); - audit_log_format(audit_buf, - " cipso_doi=%u cipso_type=%s res=%u", - doi, - type_str, - ret_val == 0 ? 1 : 0); - audit_log_end(audit_buf); + if (ret_val == 0) { + doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); + audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD, + NETLINK_CB(skb).sid); + audit_log_format(audit_buf, " doi=%u type=%s", doi, type_str); + audit_log_end(audit_buf); + } return ret_val; } @@ -673,25 +668,20 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) int ret_val = -EINVAL; u32 doi = 0; struct audit_buffer *audit_buf; - struct netlbl_audit audit_info; - if (!info->attrs[NLBL_CIPSOV4_A_DOI]) - return -EINVAL; + if (info->attrs[NLBL_CIPSOV4_A_DOI]) { + doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); + ret_val = cipso_v4_doi_remove(doi, + NETLINK_CB(skb).sid, + netlbl_cipsov4_doi_free); + } - doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); - netlbl_netlink_auditinfo(skb, &audit_info); - - ret_val = cipso_v4_doi_remove(doi, - &audit_info, - netlbl_cipsov4_doi_free); - - audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL, - &audit_info); - audit_log_format(audit_buf, - " cipso_doi=%u res=%u", - doi, - ret_val == 0 ? 1 : 0); - audit_log_end(audit_buf); + if (ret_val == 0) { + audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL, + NETLINK_CB(skb).sid); + audit_log_format(audit_buf, " doi=%u", doi); + audit_log_end(audit_buf); + } return ret_val; } diff --git a/trunk/net/netlabel/netlabel_domainhash.c b/trunk/net/netlabel/netlabel_domainhash.c index af4371d3b459..d64e2ae3b129 100644 --- a/trunk/net/netlabel/netlabel_domainhash.c +++ b/trunk/net/netlabel/netlabel_domainhash.c @@ -188,7 +188,7 @@ int netlbl_domhsh_init(u32 size) /** * netlbl_domhsh_add - Adds a entry to the domain hash table * @entry: the entry to add - * @audit_info: NetLabel audit information + * @audit_secid: the LSM secid to use in the audit message * * Description: * Adds a new entry to the domain hash table and handles any updates to the @@ -196,8 +196,7 @@ int netlbl_domhsh_init(u32 size) * negative on failure. * */ -int netlbl_domhsh_add(struct netlbl_dom_map *entry, - struct netlbl_audit *audit_info) +int netlbl_domhsh_add(struct netlbl_dom_map *entry, u32 audit_secid) { int ret_val; u32 bkt; @@ -242,26 +241,26 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, spin_unlock(&netlbl_domhsh_def_lock); } else ret_val = -EINVAL; - - if (entry->domain != NULL) - audit_domain = entry->domain; - else - audit_domain = "(default)"; - audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); - audit_log_format(audit_buf, " nlbl_domain=%s", audit_domain); - switch (entry->type) { - case NETLBL_NLTYPE_UNLABELED: - audit_log_format(audit_buf, " nlbl_protocol=unlbl"); - break; - case NETLBL_NLTYPE_CIPSOV4: - audit_log_format(audit_buf, - " nlbl_protocol=cipsov4 cipso_doi=%u", - entry->type_def.cipsov4->doi); - break; + if (ret_val == 0) { + if (entry->domain != NULL) + audit_domain = entry->domain; + else + audit_domain = "(default)"; + audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, + audit_secid); + audit_log_format(audit_buf, " domain=%s", audit_domain); + switch (entry->type) { + case NETLBL_NLTYPE_UNLABELED: + audit_log_format(audit_buf, " protocol=unlbl"); + break; + case NETLBL_NLTYPE_CIPSOV4: + audit_log_format(audit_buf, + " protocol=cipsov4 doi=%u", + entry->type_def.cipsov4->doi); + break; + } + audit_log_end(audit_buf); } - audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); - audit_log_end(audit_buf); - rcu_read_unlock(); if (ret_val != 0) { @@ -280,7 +279,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, /** * netlbl_domhsh_add_default - Adds the default entry to the domain hash table * @entry: the entry to add - * @audit_info: NetLabel audit information + * @audit_secid: the LSM secid to use in the audit message * * Description: * Adds a new default entry to the domain hash table and handles any updates @@ -288,16 +287,15 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, * negative on failure. * */ -int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, - struct netlbl_audit *audit_info) +int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, u32 audit_secid) { - return netlbl_domhsh_add(entry, audit_info); + return netlbl_domhsh_add(entry, audit_secid); } /** * netlbl_domhsh_remove - Removes an entry from the domain hash table * @domain: the domain to remove - * @audit_info: NetLabel audit information + * @audit_secid: the LSM secid to use in the audit message * * Description: * Removes an entry from the domain hash table and handles any updates to the @@ -305,7 +303,7 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, * negative on failure. * */ -int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) +int netlbl_domhsh_remove(const char *domain, u32 audit_secid) { int ret_val = -ENOENT; struct netlbl_dom_map *entry; @@ -347,20 +345,18 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) ret_val = -ENOENT; spin_unlock(&netlbl_domhsh_def_lock); } + if (ret_val == 0) { + if (entry->domain != NULL) + audit_domain = entry->domain; + else + audit_domain = "(default)"; + audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, + audit_secid); + audit_log_format(audit_buf, " domain=%s", audit_domain); + audit_log_end(audit_buf); - if (entry->domain != NULL) - audit_domain = entry->domain; - else - audit_domain = "(default)"; - audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info); - audit_log_format(audit_buf, - " nlbl_domain=%s res=%u", - audit_domain, - ret_val == 0 ? 1 : 0); - audit_log_end(audit_buf); - - if (ret_val == 0) call_rcu(&entry->rcu, netlbl_domhsh_free_entry); + } remove_return: rcu_read_unlock(); @@ -369,7 +365,7 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) /** * netlbl_domhsh_remove_default - Removes the default entry from the table - * @audit_info: NetLabel audit information + * @audit_secid: the LSM secid to use in the audit message * * Description: * Removes/resets the default entry for the domain hash table and handles any @@ -377,9 +373,9 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) * success, non-zero on failure. * */ -int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info) +int netlbl_domhsh_remove_default(u32 audit_secid) { - return netlbl_domhsh_remove(NULL, audit_info); + return netlbl_domhsh_remove(NULL, audit_secid); } /** diff --git a/trunk/net/netlabel/netlabel_domainhash.h b/trunk/net/netlabel/netlabel_domainhash.h index 3689956c3436..d50f13cacdca 100644 --- a/trunk/net/netlabel/netlabel_domainhash.h +++ b/trunk/net/netlabel/netlabel_domainhash.h @@ -57,11 +57,9 @@ struct netlbl_dom_map { int netlbl_domhsh_init(u32 size); /* Manipulate the domain hash table */ -int netlbl_domhsh_add(struct netlbl_dom_map *entry, - struct netlbl_audit *audit_info); -int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, - struct netlbl_audit *audit_info); -int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); +int netlbl_domhsh_add(struct netlbl_dom_map *entry, u32 audit_secid); +int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, u32 audit_secid); +int netlbl_domhsh_remove_default(u32 audit_secid); struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); int netlbl_domhsh_walk(u32 *skip_bkt, u32 *skip_chain, diff --git a/trunk/net/netlabel/netlabel_mgmt.c b/trunk/net/netlabel/netlabel_mgmt.c index 53c9079ad2c3..0ac314f18ad1 100644 --- a/trunk/net/netlabel/netlabel_mgmt.c +++ b/trunk/net/netlabel/netlabel_mgmt.c @@ -87,14 +87,11 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info) struct netlbl_dom_map *entry = NULL; size_t tmp_size; u32 tmp_val; - struct netlbl_audit audit_info; if (!info->attrs[NLBL_MGMT_A_DOMAIN] || !info->attrs[NLBL_MGMT_A_PROTOCOL]) goto add_failure; - netlbl_netlink_auditinfo(skb, &audit_info); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (entry == NULL) { ret_val = -ENOMEM; @@ -111,7 +108,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info) switch (entry->type) { case NETLBL_NLTYPE_UNLABELED: - ret_val = netlbl_domhsh_add(entry, &audit_info); + ret_val = netlbl_domhsh_add(entry, NETLINK_CB(skb).sid); break; case NETLBL_NLTYPE_CIPSOV4: if (!info->attrs[NLBL_MGMT_A_CV4DOI]) @@ -128,7 +125,7 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info) rcu_read_unlock(); goto add_failure; } - ret_val = netlbl_domhsh_add(entry, &audit_info); + ret_val = netlbl_domhsh_add(entry, NETLINK_CB(skb).sid); rcu_read_unlock(); break; default: @@ -159,15 +156,12 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info) static int netlbl_mgmt_remove(struct sk_buff *skb, struct genl_info *info) { char *domain; - struct netlbl_audit audit_info; if (!info->attrs[NLBL_MGMT_A_DOMAIN]) return -EINVAL; - netlbl_netlink_auditinfo(skb, &audit_info); - domain = nla_data(info->attrs[NLBL_MGMT_A_DOMAIN]); - return netlbl_domhsh_remove(domain, &audit_info); + return netlbl_domhsh_remove(domain, NETLINK_CB(skb).sid); } /** @@ -270,13 +264,10 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info) int ret_val = -EINVAL; struct netlbl_dom_map *entry = NULL; u32 tmp_val; - struct netlbl_audit audit_info; if (!info->attrs[NLBL_MGMT_A_PROTOCOL]) goto adddef_failure; - netlbl_netlink_auditinfo(skb, &audit_info); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (entry == NULL) { ret_val = -ENOMEM; @@ -286,7 +277,8 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info) switch (entry->type) { case NETLBL_NLTYPE_UNLABELED: - ret_val = netlbl_domhsh_add_default(entry, &audit_info); + ret_val = netlbl_domhsh_add_default(entry, + NETLINK_CB(skb).sid); break; case NETLBL_NLTYPE_CIPSOV4: if (!info->attrs[NLBL_MGMT_A_CV4DOI]) @@ -303,7 +295,8 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info) rcu_read_unlock(); goto adddef_failure; } - ret_val = netlbl_domhsh_add_default(entry, &audit_info); + ret_val = netlbl_domhsh_add_default(entry, + NETLINK_CB(skb).sid); rcu_read_unlock(); break; default: @@ -331,11 +324,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info) */ static int netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info) { - struct netlbl_audit audit_info; - - netlbl_netlink_auditinfo(skb, &audit_info); - - return netlbl_domhsh_remove_default(&audit_info); + return netlbl_domhsh_remove_default(NETLINK_CB(skb).sid); } /** diff --git a/trunk/net/netlabel/netlabel_unlabeled.c b/trunk/net/netlabel/netlabel_unlabeled.c index 1833ad233b39..ab36675fee8c 100644 --- a/trunk/net/netlabel/netlabel_unlabeled.c +++ b/trunk/net/netlabel/netlabel_unlabeled.c @@ -70,25 +70,18 @@ static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { /** * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag * @value: desired value - * @audit_info: NetLabel audit information + * @audit_secid: the LSM secid to use in the audit message * * Description: * Set the value of the unlabeled accept flag to @value. * */ -static void netlbl_unlabel_acceptflg_set(u8 value, - struct netlbl_audit *audit_info) +static void netlbl_unlabel_acceptflg_set(u8 value, u32 audit_secid) { - struct audit_buffer *audit_buf; - u8 old_val; - - old_val = atomic_read(&netlabel_unlabel_accept_flg); atomic_set(&netlabel_unlabel_accept_flg, value); - - audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, - audit_info); - audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val); - audit_log_end(audit_buf); + netlbl_audit_nomsg((value ? + AUDIT_MAC_UNLBL_ACCEPT : AUDIT_MAC_UNLBL_DENY), + audit_secid); } /* @@ -108,13 +101,12 @@ static void netlbl_unlabel_acceptflg_set(u8 value, static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info) { u8 value; - struct netlbl_audit audit_info; if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) { value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]); if (value == 1 || value == 0) { - netlbl_netlink_auditinfo(skb, &audit_info); - netlbl_unlabel_acceptflg_set(value, &audit_info); + netlbl_unlabel_acceptflg_set(value, + NETLINK_CB(skb).sid); return 0; } } @@ -258,23 +250,19 @@ int netlbl_unlabel_defconf(void) { int ret_val; struct netlbl_dom_map *entry; - struct netlbl_audit audit_info; + u32 secid; - /* Only the kernel is allowed to call this function and the only time - * it is called is at bootup before the audit subsystem is reporting - * messages so don't worry to much about these values. */ - security_task_getsecid(current, &audit_info.secid); - audit_info.loginuid = 0; + security_task_getsecid(current, &secid); entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (entry == NULL) return -ENOMEM; entry->type = NETLBL_NLTYPE_UNLABELED; - ret_val = netlbl_domhsh_add_default(entry, &audit_info); + ret_val = netlbl_domhsh_add_default(entry, secid); if (ret_val != 0) return ret_val; - netlbl_unlabel_acceptflg_set(1, &audit_info); + netlbl_unlabel_acceptflg_set(1, secid); return 0; } diff --git a/trunk/net/netlabel/netlabel_user.c b/trunk/net/netlabel/netlabel_user.c index 98a416381e61..c2343af584cb 100644 --- a/trunk/net/netlabel/netlabel_user.c +++ b/trunk/net/netlabel/netlabel_user.c @@ -85,7 +85,7 @@ int netlbl_netlink_init(void) /** * netlbl_audit_start_common - Start an audit message * @type: audit message type - * @audit_info: NetLabel audit information + * @secid: LSM context ID * * Description: * Start an audit message using the type specified in @type and fill the audit @@ -93,11 +93,14 @@ int netlbl_netlink_init(void) * a pointer to the audit buffer on success, NULL on failure. * */ -struct audit_buffer *netlbl_audit_start_common(int type, - struct netlbl_audit *audit_info) +struct audit_buffer *netlbl_audit_start_common(int type, u32 secid) { struct audit_context *audit_ctx = current->audit_context; struct audit_buffer *audit_buf; + uid_t audit_loginuid; + const char *audit_tty; + char audit_comm[sizeof(current->comm)]; + struct vm_area_struct *vma; char *secctx; u32 secctx_len; @@ -105,13 +108,60 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_buf == NULL) return NULL; - audit_log_format(audit_buf, "netlabel: auid=%u", audit_info->loginuid); + audit_loginuid = audit_get_loginuid(audit_ctx); + if (current->signal && + current->signal->tty && + current->signal->tty->name) + audit_tty = current->signal->tty->name; + else + audit_tty = "(none)"; + get_task_comm(audit_comm, current); - if (audit_info->secid != 0 && - security_secid_to_secctx(audit_info->secid, - &secctx, - &secctx_len) == 0) + audit_log_format(audit_buf, + "netlabel: auid=%u uid=%u tty=%s pid=%d", + audit_loginuid, + current->uid, + audit_tty, + current->pid); + audit_log_format(audit_buf, " comm="); + audit_log_untrustedstring(audit_buf, audit_comm); + if (current->mm) { + down_read(¤t->mm->mmap_sem); + vma = current->mm->mmap; + while (vma) { + if ((vma->vm_flags & VM_EXECUTABLE) && + vma->vm_file) { + audit_log_d_path(audit_buf, + " exe=", + vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt); + break; + } + vma = vma->vm_next; + } + up_read(¤t->mm->mmap_sem); + } + + if (secid != 0 && + security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) audit_log_format(audit_buf, " subj=%s", secctx); return audit_buf; } + +/** + * netlbl_audit_nomsg - Send an audit message without additional text + * @type: audit message type + * @secid: LSM context ID + * + * Description: + * Send an audit message with only the common NetLabel audit fields. + * + */ +void netlbl_audit_nomsg(int type, u32 secid) +{ + struct audit_buffer *audit_buf; + + audit_buf = netlbl_audit_start_common(type, secid); + audit_log_end(audit_buf); +} diff --git a/trunk/net/netlabel/netlabel_user.h b/trunk/net/netlabel/netlabel_user.h index 47967ef32964..ab840acfc964 100644 --- a/trunk/net/netlabel/netlabel_user.h +++ b/trunk/net/netlabel/netlabel_user.h @@ -72,25 +72,13 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb, NETLBL_PROTO_VERSION); } -/** - * netlbl_netlink_auditinfo - Fetch the audit information from a NETLINK msg - * @skb: the packet - * @audit_info: NetLabel audit information - */ -static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, - struct netlbl_audit *audit_info) -{ - audit_info->secid = NETLINK_CB(skb).sid; - audit_info->loginuid = NETLINK_CB(skb).loginuid; -} - /* NetLabel NETLINK I/O functions */ int netlbl_netlink_init(void); /* NetLabel Audit Functions */ -struct audit_buffer *netlbl_audit_start_common(int type, - struct netlbl_audit *audit_info); +struct audit_buffer *netlbl_audit_start_common(int type, u32 secid); +void netlbl_audit_nomsg(int type, u32 secid); #endif diff --git a/trunk/net/sctp/input.c b/trunk/net/sctp/input.c index 64f630102532..03f65de75d88 100644 --- a/trunk/net/sctp/input.c +++ b/trunk/net/sctp/input.c @@ -218,6 +218,12 @@ int sctp_rcv(struct sk_buff *skb) } } + /* SCTP seems to always need a timestamp right now (FIXME) */ + if (skb->tstamp.off_sec == 0) { + __net_timestamp(skb); + sock_enable_timestamp(sk); + } + if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family)) goto discard_release; nf_reset(skb); @@ -382,7 +388,7 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, * pmtu discovery on this transport. */ t->pathmtu = SCTP_DEFAULT_MINSEGMENT; - t->param_flags = (t->param_flags & ~SPP_PMTUD) | + t->param_flags = (t->param_flags & ~SPP_HB) | SPP_PMTUD_DISABLE; } else { t->pathmtu = pmtu; diff --git a/trunk/net/sctp/output.c b/trunk/net/sctp/output.c index 3ef4351dd956..cdc5a3936766 100644 --- a/trunk/net/sctp/output.c +++ b/trunk/net/sctp/output.c @@ -633,7 +633,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, * data will fit or delay in hopes of bundling a full * sized packet. */ - if (len < asoc->frag_point) { + if (len < asoc->pathmtu - packet->overhead) { retval = SCTP_XMIT_NAGLE_DELAY; goto finish; } @@ -645,13 +645,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, /* Keep track of how many bytes are in flight to the receiver. */ asoc->outqueue.outstanding_bytes += datasize; - /* Update our view of the receiver's rwnd. Include sk_buff overhead - * while updating peer.rwnd so that it reduces the chances of a - * receiver running out of receive buffer space even when receive - * window is still open. This can happen when a sender is sending - * sending small messages. - */ - datasize += sizeof(struct sk_buff); + /* Update our view of the receiver's rwnd. */ if (datasize < rwnd) rwnd -= datasize; else diff --git a/trunk/net/sctp/outqueue.c b/trunk/net/sctp/outqueue.c index 739582415bf6..37074a39ecbb 100644 --- a/trunk/net/sctp/outqueue.c +++ b/trunk/net/sctp/outqueue.c @@ -416,8 +416,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, * (Section 7.2.4)), add the data size of those * chunks to the rwnd. */ - q->asoc->peer.rwnd += (sctp_data_size(chunk) + - sizeof(struct sk_buff)); + q->asoc->peer.rwnd += sctp_data_size(chunk); q->outstanding_bytes -= sctp_data_size(chunk); transport->flight_size -= sctp_data_size(chunk); diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index 507dff72c585..7745bdea7817 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -1447,16 +1447,8 @@ struct sctp_association *sctp_unpack_cookie( /* Check to see if the cookie is stale. If there is already * an association, there is no need to check cookie's expiration * for init collision case of lost COOKIE ACK. - * If skb has been timestamped, then use the stamp, otherwise - * use current time. This introduces a small possibility that - * that a cookie may be considered expired, but his would only slow - * down the new association establishment instead of every packet. */ - if (sock_flag(ep->base.sk, SOCK_TIMESTAMP)) - skb_get_timestamp(skb, &tv); - else - do_gettimeofday(&tv); - + skb_get_timestamp(skb, &tv); if (!asoc && tv_lt(bear_cookie->expiration, tv)) { __u16 len; /* diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 3fe906d65069..79c3e072cf28 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -3084,8 +3084,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) */ sp->disable_fragments = 0; - /* Enable Nagle algorithm by default. */ - sp->nodelay = 0; + /* Turn on/off any Nagle-like algorithm. */ + sp->nodelay = 1; /* Enable by default. */ sp->v4mapped = 1;