fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / atm / mpc.c
index a28db2d..c18f737 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/capability.h>
 #include <linux/seq_file.h>
 
 /* We are an ethernet device */
@@ -24,7 +25,6 @@
 #include <linux/atmlec.h>
 #include <linux/atmmpc.h>
 /* Modular too */
-#include <linux/config.h>
 #include <linux/module.h>
 
 #include "lec.h"
@@ -98,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)
@@ -157,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;
 
@@ -182,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;
 
@@ -228,20 +223,15 @@ int atm_mpoa_delete_qos(struct atm_mpoa_qos *entry)
 /* 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;
        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));
                seq_printf(m, "%u.%u.%u.%u\n     %-7d %-7d %-7d %-7d %-7d\n     %-7d %-7d %-7d %-7d %-7d\n",
-                               NIPQUAD(ipaddr),
+                               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;
@@ -263,10 +253,9 @@ 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));
        rwlock_init(&mpc->ingress_lock);
        rwlock_init(&mpc->egress_lock);
        mpc->next = mpcs;
@@ -471,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
@@ -522,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++;
@@ -552,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++;
@@ -564,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) {
@@ -594,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 {
@@ -627,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);
        }
@@ -653,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);
@@ -665,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;
        }
 
@@ -696,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) {
@@ -751,7 +738,7 @@ 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;
@@ -794,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);
 
@@ -853,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);
        }
@@ -873,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");
@@ -938,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);
@@ -950,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;
 }
@@ -1039,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);
@@ -1076,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);
 
@@ -1091,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;
                }
@@ -1113,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);
@@ -1161,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);
@@ -1187,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) {
@@ -1206,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;
 
@@ -1229,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;
@@ -1333,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;
 }
@@ -1440,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);