X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fatm%2Fmpc.c;h=c18f73715ef9799acdc6177f3d2470eb4f10f196;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=e629e89d4df41dc3c5762ec23043b827f3dfe00b;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/net/atm/mpc.c b/net/atm/mpc.c index e629e89d4..c18f73715 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include /* We are an ethernet device */ #include @@ -23,7 +25,6 @@ #include #include /* Modular too */ -#include #include #include "lec.h" @@ -97,14 +98,9 @@ static struct notifier_block mpoa_notifier = { 0 }; -#ifdef CONFIG_PROC_FS -extern int mpc_proc_init(void); -extern void mpc_proc_clean(void); -#endif - struct mpoa_client *mpcs = NULL; /* FIXME */ static struct atm_mpoa_qos *qos_head = NULL; -static struct timer_list mpc_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(mpc_timer, NULL, 0, 0); static struct mpoa_client *find_mpc_by_itfnum(int itf) @@ -156,7 +152,7 @@ static struct mpoa_client *find_mpc_by_lec(struct net_device *dev) /* * Overwrites the old entry or makes a new one. */ -struct atm_mpoa_qos *atm_mpoa_add_qos(uint32_t dst_ip, struct atm_qos *qos) +struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos) { struct atm_mpoa_qos *entry; @@ -181,7 +177,7 @@ struct atm_mpoa_qos *atm_mpoa_add_qos(uint32_t dst_ip, struct atm_qos *qos) return entry; } -struct atm_mpoa_qos *atm_mpoa_search_qos(uint32_t dst_ip) +struct atm_mpoa_qos *atm_mpoa_search_qos(__be32 dst_ip) { struct atm_mpoa_qos *qos; @@ -224,29 +220,22 @@ int atm_mpoa_delete_qos(struct atm_mpoa_qos *entry) return 0; } -void atm_mpoa_disp_qos(char *page, ssize_t *len) +/* this is buggered - we need locking for qos_head */ +void atm_mpoa_disp_qos(struct seq_file *m) { - - unsigned char *ip; - char ipaddr[16]; struct atm_mpoa_qos *qos; qos = qos_head; - *len += sprintf(page + *len, "QoS entries for shortcuts:\n"); - *len += sprintf(page + *len, "IP address\n TX:max_pcr pcr min_pcr max_cdv max_sdu\n RX:max_pcr pcr min_pcr max_cdv max_sdu\n"); + seq_printf(m, "QoS entries for shortcuts:\n"); + seq_printf(m, "IP address\n TX:max_pcr pcr min_pcr max_cdv max_sdu\n RX:max_pcr pcr min_pcr max_cdv max_sdu\n"); - ipaddr[sizeof(ipaddr)-1] = '\0'; while (qos != NULL) { - ip = (unsigned char *)&qos->ipaddr; - sprintf(ipaddr, "%u.%u.%u.%u", NIPQUAD(ip)); - *len += sprintf(page + *len, "%u.%u.%u.%u\n %-7d %-7d %-7d %-7d %-7d\n %-7d %-7d %-7d %-7d %-7d\n", - NIPQUAD(ipaddr), + seq_printf(m, "%u.%u.%u.%u\n %-7d %-7d %-7d %-7d %-7d\n %-7d %-7d %-7d %-7d %-7d\n", + NIPQUAD(qos->ipaddr), qos->qos.txtp.max_pcr, qos->qos.txtp.pcr, qos->qos.txtp.min_pcr, qos->qos.txtp.max_cdv, qos->qos.txtp.max_sdu, qos->qos.rxtp.max_pcr, qos->qos.rxtp.pcr, qos->qos.rxtp.min_pcr, qos->qos.rxtp.max_cdv, qos->qos.rxtp.max_sdu); qos = qos->next; } - - return; } static struct net_device *find_lec_by_itfnum(int itf) @@ -264,12 +253,11 @@ static struct mpoa_client *alloc_mpc(void) { struct mpoa_client *mpc; - mpc = kmalloc(sizeof (struct mpoa_client), GFP_KERNEL); + mpc = kzalloc(sizeof (struct mpoa_client), GFP_KERNEL); if (mpc == NULL) return NULL; - memset(mpc, 0, sizeof(struct mpoa_client)); - mpc->ingress_lock = RW_LOCK_UNLOCKED; - mpc->egress_lock = RW_LOCK_UNLOCKED; + rwlock_init(&mpc->ingress_lock); + rwlock_init(&mpc->egress_lock); mpc->next = mpcs; atm_mpoa_init_cache(mpc); @@ -472,11 +460,11 @@ static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc) in_cache_entry *entry; struct iphdr *iph; char *buff; - uint32_t ipaddr = 0; + __be32 ipaddr = 0; static struct { struct llc_snap_hdr hdr; - uint32_t tag; + __be32 tag; } tagged_llc_snap_hdr = { {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}, {0x88, 0x4c}}, 0 @@ -523,7 +511,7 @@ static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc) memcpy(skb->data, &llc_snap_mpoa_data, sizeof(struct llc_snap_hdr)); } - atomic_add(skb->truesize, &entry->shortcut->sk->sk_wmem_alloc); + atomic_add(skb->truesize, &sk_atm(entry->shortcut)->sk_wmem_alloc); ATM_SKB(skb)->atm_options = entry->shortcut->atm_options; entry->shortcut->send(entry->shortcut, skb); entry->packets_fwded++; @@ -553,7 +541,7 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev) goto non_ip; /* Multi-Protocol Over ATM :-) */ while (i < mpc->number_of_mps_macs) { - if (memcmp(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN), ETH_ALEN) == 0) + if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN))) if ( send_via_shortcut(skb, mpc) == 0 ) /* try shortcut */ return 0; /* success! */ i++; @@ -565,14 +553,13 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev) return retval; } -int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg) +static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg) { int bytes_left; struct mpoa_client *mpc; struct atmmpc_ioc ioc_data; in_cache_entry *in_entry; - uint32_t ipaddr; - unsigned char *ip; + __be32 ipaddr; bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc)); if (bytes_left != 0) { @@ -595,9 +582,8 @@ int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg) if (in_entry != NULL) mpc->in_ops->put(in_entry); return -EINVAL; } - ip = (unsigned char*)&in_entry->ctrl_info.in_dst_ip; printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %u.%u.%u.%u\n", - mpc->dev->name, ip[0], ip[1], ip[2], ip[3]); + mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip)); in_entry->shortcut = vcc; mpc->in_ops->put(in_entry); } else { @@ -628,10 +614,8 @@ static void mpc_vcc_close(struct atm_vcc *vcc, struct net_device *dev) dprintk("mpoa: (%s) mpc_vcc_close:\n", dev->name); in_entry = mpc->in_ops->get_by_vcc(vcc, mpc); if (in_entry) { - unsigned char *ip __attribute__ ((unused)) = - (unsigned char *)&in_entry->ctrl_info.in_dst_ip; dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %u.%u.%u.%u\n", - mpc->dev->name, ip[0], ip[1], ip[2], ip[3]); + mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip)); in_entry->shortcut = NULL; mpc->in_ops->put(in_entry); } @@ -654,7 +638,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb) struct sk_buff *new_skb; eg_cache_entry *eg; struct mpoa_client *mpc; - uint32_t tag; + __be32 tag; char *tmp; ddprintk("mpoa: (%s) mpc_push:\n", dev->name); @@ -666,10 +650,12 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb) skb->dev = dev; if (memcmp(skb->data, &llc_snap_mpoa_ctrl, sizeof(struct llc_snap_hdr)) == 0) { + struct sock *sk = sk_atm(vcc); + dprintk("mpoa: (%s) mpc_push: control packet arrived\n", dev->name); /* Pass control packets to daemon */ - skb_queue_tail(&vcc->sk->sk_receive_queue, skb); - vcc->sk->sk_data_ready(vcc->sk, skb->len); + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); return; } @@ -697,7 +683,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb) } tmp = skb->data + sizeof(struct llc_snap_hdr); - tag = *(uint32_t *)tmp; + tag = *(__be32 *)tmp; eg = mpc->eg_ops->get_by_tag(tag, mpc); if (eg == NULL) { @@ -752,17 +738,22 @@ static struct atm_dev mpc_dev = { /* members not explicitly initialised will be 0 */ }; -int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg) +static int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg) { struct mpoa_client *mpc; struct lec_priv *priv; + int err; if (mpcs == NULL) { init_timer(&mpc_timer); mpc_timer_refresh(); /* This lets us now how our LECs are doing */ - register_netdevice_notifier(&mpoa_notifier); + err = register_netdevice_notifier(&mpoa_notifier); + if (err < 0) { + del_timer(&mpc_timer); + return err; + } } mpc = find_mpc_by_itfnum(arg); @@ -790,7 +781,7 @@ int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg) mpc->mpoad_vcc = vcc; vcc->dev = &mpc_dev; - vcc_insert_socket(vcc->sk); + vcc_insert_socket(sk_atm(vcc)); set_bit(ATM_VF_META,&vcc->flags); set_bit(ATM_VF_READY,&vcc->flags); @@ -849,7 +840,7 @@ static void mpoad_close(struct atm_vcc *vcc) mpc->in_ops->destroy_cache(mpc); mpc->eg_ops->destroy_cache(mpc); - while ((skb = skb_dequeue(&vcc->sk->sk_receive_queue))) { + while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue))) { atm_return(vcc, skb->truesize); kfree_skb(skb); } @@ -869,7 +860,7 @@ static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb) struct mpoa_client *mpc = find_mpc_by_vcc(vcc); struct k_message *mesg = (struct k_message*)skb->data; - atomic_sub(skb->truesize, &vcc->sk->sk_wmem_alloc); + atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc); if (mpc == NULL) { printk("mpoa: msg_from_mpoad: no mpc found\n"); @@ -934,6 +925,7 @@ static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb) int msg_to_mpoad(struct k_message *mesg, struct mpoa_client *mpc) { struct sk_buff *skb; + struct sock *sk; if (mpc == NULL || !mpc->mpoad_vcc) { printk("mpoa: msg_to_mpoad: mesg %d to a non-existent mpoad\n", mesg->type); @@ -946,8 +938,10 @@ int msg_to_mpoad(struct k_message *mesg, struct mpoa_client *mpc) skb_put(skb, sizeof(struct k_message)); memcpy(skb->data, mesg, sizeof(struct k_message)); atm_force_charge(mpc->mpoad_vcc, skb->truesize); - skb_queue_tail(&mpc->mpoad_vcc->sk->sk_receive_queue, skb); - mpc->mpoad_vcc->sk->sk_data_ready(mpc->mpoad_vcc->sk, skb->len); + + sk = sk_atm(mpc->mpoad_vcc); + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); return 0; } @@ -1035,7 +1029,7 @@ static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned lo static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc) { - uint32_t dst_ip = msg->content.in_info.in_dst_ip; + __be32 dst_ip = msg->content.in_info.in_dst_ip; in_cache_entry *entry; entry = mpc->in_ops->get(dst_ip, mpc); @@ -1072,8 +1066,7 @@ static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc) */ static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_client *client, in_cache_entry *entry) { - uint32_t dst_ip = msg->content.in_info.in_dst_ip; - unsigned char *ip __attribute__ ((unused)) = (unsigned char *)&dst_ip; + __be32 dst_ip = msg->content.in_info.in_dst_ip; struct atm_mpoa_qos *qos = atm_mpoa_search_qos(dst_ip); eg_cache_entry *eg_entry = client->eg_ops->get_by_src_ip(dst_ip, client); @@ -1087,7 +1080,7 @@ static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_clien entry->shortcut = eg_entry->shortcut; } if(entry->shortcut){ - dprintk("mpoa: (%s) using egress SVC to reach %u.%u.%u.%u\n",client->dev->name, NIPQUAD(ip)); + dprintk("mpoa: (%s) using egress SVC to reach %u.%u.%u.%u\n",client->dev->name, NIPQUAD(dst_ip)); client->eg_ops->put(eg_entry); return; } @@ -1109,12 +1102,10 @@ static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_clien static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc) { - unsigned char *ip; - - uint32_t dst_ip = msg->content.in_info.in_dst_ip; + __be32 dst_ip = msg->content.in_info.in_dst_ip; in_cache_entry *entry = mpc->in_ops->get(dst_ip, mpc); - ip = (unsigned char *)&dst_ip; - dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %u.%u.%u.%u\n", mpc->dev->name, NIPQUAD(ip)); + + dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %u.%u.%u.%u\n", mpc->dev->name, NIPQUAD(dst_ip)); ddprintk("mpoa: (%s) MPOA_res_reply_rcvd() entry = %p", mpc->dev->name, entry); if(entry == NULL){ printk("\nmpoa: (%s) ARGH, received res. reply for an entry that doesn't exist.\n", mpc->dev->name); @@ -1157,20 +1148,19 @@ static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc) static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc) { - uint32_t dst_ip = msg->content.in_info.in_dst_ip; - uint32_t mask = msg->ip_mask; - unsigned char *ip = (unsigned char *)&dst_ip; + __be32 dst_ip = msg->content.in_info.in_dst_ip; + __be32 mask = msg->ip_mask; in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask); if(entry == NULL){ printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ", mpc->dev->name); - printk("ip = %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]); + printk("ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip)); return; } do { dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %u.%u.%u.%u\n" , - mpc->dev->name, ip[0], ip[1], ip[2], ip[3]); + mpc->dev->name, NIPQUAD(dst_ip)); write_lock_bh(&mpc->ingress_lock); mpc->in_ops->remove_entry(entry, mpc); write_unlock_bh(&mpc->ingress_lock); @@ -1183,7 +1173,7 @@ static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc) static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc) { - uint32_t cache_id = msg->content.eg_info.cache_id; + __be32 cache_id = msg->content.eg_info.cache_id; eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(cache_id, mpc); if (entry == NULL) { @@ -1202,6 +1192,7 @@ static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc) static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry) { + struct sock *sk; struct k_message *purge_msg; struct sk_buff *skb; @@ -1225,8 +1216,10 @@ static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry) purge_msg->content.eg_info = entry->ctrl_info; atm_force_charge(vcc, skb->truesize); - skb_queue_tail(&vcc->sk->sk_receive_queue, skb); - vcc->sk->sk_data_ready(vcc->sk, skb->len); + + sk = sk_atm(vcc); + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); dprintk("mpoa: purge_egress_shortcut: exiting:\n"); return; @@ -1329,13 +1322,12 @@ static void set_mps_mac_addr_rcvd(struct k_message *msg, struct mpoa_client *cli if(client->number_of_mps_macs) kfree(client->mps_macs); client->number_of_mps_macs = 0; - client->mps_macs = kmalloc(ETH_ALEN,GFP_KERNEL); + client->mps_macs = kmemdup(msg->MPS_ctrl, ETH_ALEN, GFP_KERNEL); if (client->mps_macs == NULL) { printk("mpoa: set_mps_mac_addr_rcvd: out of memory\n"); return; } client->number_of_mps_macs = 1; - memcpy(client->mps_macs, msg->MPS_ctrl, ETH_ALEN); return; } @@ -1436,27 +1428,21 @@ static __init int atm_mpoa_init(void) { register_atm_ioctl(&atm_ioctl_ops); -#ifdef CONFIG_PROC_FS if (mpc_proc_init() != 0) printk(KERN_INFO "mpoa: failed to initialize /proc/mpoa\n"); - else - printk(KERN_INFO "mpoa: /proc/mpoa initialized\n"); -#endif printk("mpc.c: " __DATE__ " " __TIME__ " initialized\n"); return 0; } -void __exit atm_mpoa_cleanup(void) +static void __exit atm_mpoa_cleanup(void) { struct mpoa_client *mpc, *tmp; struct atm_mpoa_qos *qos, *nextqos; struct lec_priv *priv; -#ifdef CONFIG_PROC_FS mpc_proc_clean(); -#endif del_timer(&mpc_timer); unregister_netdevice_notifier(&mpoa_notifier);