static ssize_t show_atmaddress(struct class_device *cdev, char *buf)
{
- unsigned long flags;
+ unsigned long flags;
char *pos = buf;
struct atm_dev *adev = to_atm_dev(cdev);
- struct atm_dev_addr *aaddr;
+ struct atm_dev_addr *aaddr;
int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin;
int i, j;
- spin_lock_irqsave(&adev->lock, flags);
- list_for_each_entry(aaddr, &adev->local, entry) {
+ spin_lock_irqsave(&adev->lock, flags);
+ list_for_each_entry(aaddr, &adev->local, entry) {
for(i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) {
if (j == *fmt) {
pos += sprintf(pos, ".");
}
pos += sprintf(pos, "\n");
}
- spin_unlock_irqrestore(&adev->lock, flags);
+ spin_unlock_irqrestore(&adev->lock, flags);
return pos - buf;
}
pos += sprintf(pos, "%d\n",
adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
-
+
return pos - buf;
}
link_rate = adev->link_rate * 8 * 53;
}
pos += sprintf(pos, "%d\n", link_rate);
-
+
return pos - buf;
}
ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
if (!atm_may_send(atmvcc, skb->truesize)) {
- /* we free this here for now, because we cannot know in a higher
+ /* we free this here for now, because we cannot know in a higher
layer whether the skb point it supplied wasn't freed yet.
now, it always is.
*/
++*pos;
- brd = list_entry(brd->br2684_devs.next,
+ brd = list_entry(brd->br2684_devs.next,
struct br2684_dev, br2684_devs);
return (&brd->br2684_devs != &br2684_devs) ? brd : NULL;
}
struct atm_vcc *vcc = atm_sk(sk);
return (vcc->qos.txtp.max_sdu +
- atomic_read(&sk->sk_wmem_alloc)) <= sk->sk_sndbuf;
+ atomic_read(&sk->sk_wmem_alloc)) <= sk->sk_sndbuf;
}
static void vcc_write_space(struct sock *sk)
-{
+{
read_lock(&sk->sk_callback_lock);
if (vcc_writable(sk)) {
.owner = THIS_MODULE,
.obj_size = sizeof(struct atm_vcc),
};
-
+
int vcc_create(struct socket *sock, int protocol, int family)
{
struct sock *sk;
return error;
vcc->dev = dev;
write_lock_irq(&vcc_sklist_lock);
- if (test_bit(ATM_DF_REMOVED, &dev->flags) ||
+ if (test_bit(ATM_DF_REMOVED, &dev->flags) ||
(error = find_ci(vcc, &vpi, &vci))) {
write_unlock_irq(&vcc_sklist_lock);
goto fail_module_put;
if (!skb)
return error;
- copied = skb->len;
+ copied = skb->len;
if (copied > size) {
- copied = size;
+ copied = size;
msg->msg_flags |= MSG_TRUNC;
}
- error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
- if (error)
- return error;
- sock_recv_timestamp(msg, sk, skb);
- DPRINTK("RcvM %d -= %d\n", atomic_read(&sk->rmem_alloc), skb->truesize);
- atm_return(vcc, skb->truesize);
- skb_free_datagram(sk, skb);
- return copied;
+ error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+ if (error)
+ return error;
+ sock_recv_timestamp(msg, sk, skb);
+ DPRINTK("RcvM %d -= %d\n", atomic_read(&sk->rmem_alloc), skb->truesize);
+ atm_return(vcc, skb->truesize);
+ skb_free_datagram(sk, skb);
+ return copied;
}
int error;
if (!qos->txtp.traffic_class && !qos->rxtp.traffic_class)
- return -EINVAL;
+ return -EINVAL;
if (qos->txtp.traffic_class != qos->rxtp.traffic_class &&
qos->txtp.traffic_class && qos->rxtp.traffic_class &&
qos->txtp.traffic_class != ATM_ANYCLASS &&
printk(KERN_ERR "atmsvc_init() failed with %d\n", error);
goto out_atmpvc_exit;
}
- if ((error = atm_proc_init()) < 0) {
+ if ((error = atm_proc_init()) < 0) {
printk(KERN_ERR "atm_proc_init() failed with %d\n",error);
goto out_atmsvc_exit;
}
- if ((error = atm_sysfs_init()) < 0) {
+ if ((error = atm_sysfs_init()) < 0) {
printk(KERN_ERR "atm_sysfs_init() failed with %d\n",error);
goto out_atmproc_exit;
}
/* net/atm/common.h - ATM sockets (common part for PVC and SVC) */
-
+
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
}
skb = skb_peek(&sk->sk_receive_queue);
error = put_user(skb ? skb->len : 0,
- (int __user *)argp) ? -EFAULT : 0;
+ (int __user *)argp) ? -EFAULT : 0;
goto done;
}
case SIOCGSTAMP: /* borrowed from IP */
/*
- * lec.c: Lan Emulation driver
+ * lec.c: Lan Emulation driver
*
* Marko Kiiskila <mkiiskila@yahoo.com>
*/
static void lec_arp_check_expire(struct work_struct *work);
static void lec_arp_expire_arp(unsigned long data);
-/*
+/*
* Arp table funcs
*/
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);
+ INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
+ INIT_HLIST_HEAD(&priv->lec_no_forward);
+ INIT_HLIST_HEAD(&priv->mcast_fwds);
spin_lock_init(&priv->lec_arp_lock);
INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire);
schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
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,
/*
* 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,
}
/*
- * Notifies: Response to arp_request (atm_addr != NULL)
+ * Notifies: Response to arp_request (atm_addr != NULL)
*/
static void
lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
}
/*
- * Notifies: Vcc setup ready
+ * Notifies: Vcc setup ready
*/
static void
lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
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);
+ tran_id, entry);
}
}
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
/*
* ATM LAN Emulation supports both LLC & Dix Ethernet EtherType
- * frames.
+ * 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,
- * but not padding required to meet the minimum data frame length,
+ * but not padding required to meet the minimum data frame length,
* is less than 1536(0x0600) MUST be encoded by placing that length
* in the h_type field. The LLC field follows header immediatelly.
* 3. LLC data frames longer than this maximum MUST be encoded by placing
#include "resources.h"
/*
- * mpc.c: Implementation of MPOA client kernel part
+ * mpc.c: Implementation of MPOA client kernel part
*/
#if 0
0xaa, 0xaa, 0x03,
{0x00, 0x00, 0x5e},
{0x00, 0x03} /* For MPOA control PDUs */
-};
+};
static struct llc_snap_hdr llc_snap_mpoa_data = {
0xaa, 0xaa, 0x03,
{0x00, 0x00, 0x00},
{0x08, 0x00} /* This is for IP PDUs only */
-};
+};
static struct llc_snap_hdr llc_snap_mpoa_data_tagged = {
0xaa, 0xaa, 0x03,
{0x00, 0x00, 0x00},
{0x88, 0x4c} /* This is for tagged data PDUs */
-};
+};
static struct notifier_block mpoa_notifier = {
mpoa_event_listener,
static struct mpoa_client *find_mpc_by_itfnum(int itf)
{
struct mpoa_client *mpc;
-
+
mpc = mpcs; /* our global linked list */
while (mpc != NULL) {
if (mpc->dev_num == itf)
return mpc;
- mpc = mpc->next;
+ mpc = mpc->next;
}
return NULL; /* not found */
static struct mpoa_client *find_mpc_by_vcc(struct atm_vcc *vcc)
{
struct mpoa_client *mpc;
-
+
mpc = mpcs; /* our global linked list */
while (mpc != NULL) {
if (mpc->mpoad_vcc == vcc)
static struct mpoa_client *find_mpc_by_lec(struct net_device *dev)
{
struct mpoa_client *mpc;
-
+
mpc = mpcs; /* our global linked list */
while (mpc != NULL) {
if (mpc->dev == dev)
}
return qos;
-}
+}
/*
* Returns 0 for failure
sprintf(name, "lec%d", itf);
dev = dev_get_by_name(name);
-
+
return dev;
}
mpc->parameters.mpc_p2 = MPC_P2;
memset(mpc->parameters.mpc_p3,0,sizeof(mpc->parameters.mpc_p3));
mpc->parameters.mpc_p4 = MPC_P4;
- mpc->parameters.mpc_p5 = MPC_P5;
+ mpc->parameters.mpc_p5 = MPC_P5;
mpc->parameters.mpc_p6 = MPC_P6;
-
+
mpcs = mpc;
-
+
return mpc;
}
/*
*
* start_mpc() puts the MPC on line. All the packets destined
- * to the lec underneath us are now being monitored and
+ * to the lec underneath us are now being monitored and
* shortcuts will be established.
*
*/
static void start_mpc(struct mpoa_client *mpc, struct net_device *dev)
{
-
- dprintk("mpoa: (%s) start_mpc:\n", mpc->dev->name);
+
+ dprintk("mpoa: (%s) start_mpc:\n", mpc->dev->name);
if (dev->hard_start_xmit == NULL) {
printk("mpoa: (%s) start_mpc: dev->hard_start_xmit == NULL, not starting\n",
dev->name);
static void stop_mpc(struct mpoa_client *mpc)
{
-
- dprintk("mpoa: (%s) stop_mpc:", mpc->dev->name);
+
+ dprintk("mpoa: (%s) stop_mpc:", mpc->dev->name);
/* Lets not nullify lec device's dev->hard_start_xmit */
if (mpc->dev->hard_start_xmit != mpc_send_packet) {
mpc->dev->hard_start_xmit = mpc->old_hard_start_xmit;
mpc->old_hard_start_xmit = NULL;
/* close_shortcuts(mpc); ??? FIXME */
-
+
return;
}
uint8_t length, mpoa_device_type, number_of_mps_macs;
uint8_t *end_of_tlvs;
struct mpoa_client *mpc;
-
+
mpoa_device_type = number_of_mps_macs = 0; /* silence gcc */
dprintk("mpoa: (%s) lane2_assoc_ind: received TLV(s), ", dev->name);
dprintk("total length of all TLVs %d\n", sizeoftlvs);
printk("TLV value extends past its buffer, aborting parse\n");
return;
}
-
+
if (type == 0) {
printk("mpoa: (%s) lane2_assoc_ind: TLV type was 0, returning\n", dev->name);
return;
continue; /* someone should read the spec */
}
dprintk("this MPS has %d MAC addresses\n", number_of_mps_macs);
-
+
/* ok, now we can go and tell our daemon the control address of MPS */
send_set_mps_ctrl_addr(tlvs, mpc);
-
+
tlvs = copy_macs(mpc, mac_addr, tlvs, number_of_mps_macs, mpoa_device_type);
if (tlvs == NULL) return;
}
iph = (struct iphdr *)buff;
ipaddr = iph->daddr;
- ddprintk("mpoa: (%s) send_via_shortcut: ipaddr 0x%x\n", mpc->dev->name, ipaddr);
+ ddprintk("mpoa: (%s) send_via_shortcut: ipaddr 0x%x\n", mpc->dev->name, ipaddr);
entry = mpc->in_ops->get(ipaddr, mpc);
if (entry == NULL) {
return 1;
}
if (mpc->in_ops->cache_hit(entry, mpc) != OPEN){ /* threshold not exceeded or VCC not ready */
- ddprintk("mpoa: (%s) send_via_shortcut: cache_hit: returns != OPEN\n", mpc->dev->name);
+ ddprintk("mpoa: (%s) send_via_shortcut: cache_hit: returns != OPEN\n", mpc->dev->name);
mpc->in_ops->put(entry);
return 1;
}
- ddprintk("mpoa: (%s) send_via_shortcut: using shortcut\n", mpc->dev->name);
+ ddprintk("mpoa: (%s) send_via_shortcut: using shortcut\n", mpc->dev->name);
/* MPOA spec A.1.4, MPOA client must decrement IP ttl at least by one */
if (iph->ttl <= 1) {
- ddprintk("mpoa: (%s) send_via_shortcut: IP ttl = %u, using LANE\n", mpc->dev->name, iph->ttl);
+ ddprintk("mpoa: (%s) send_via_shortcut: IP ttl = %u, using LANE\n", mpc->dev->name, iph->ttl);
mpc->in_ops->put(entry);
return 1;
}
struct mpoa_client *mpc;
struct ethhdr *eth;
int i = 0;
-
+
mpc = find_mpc_by_lec(dev); /* this should NEVER fail */
if(mpc == NULL) {
printk("mpoa: (%s) mpc_send_packet: no MPC found\n", dev->name);
non_ip:
retval = mpc->old_hard_start_xmit(skb,dev);
-
+
return retval;
}
ipaddr = ioc_data.ipaddr;
if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF)
return -EINVAL;
-
+
mpc = find_mpc_by_itfnum(ioc_data.dev_num);
if (mpc == NULL)
return -EINVAL;
-
+
if (ioc_data.type == MPC_SOCKET_INGRESS) {
in_entry = mpc->in_ops->get(ipaddr, mpc);
if (in_entry == NULL || in_entry->entry_state < INGRESS_RESOLVED) {
struct mpoa_client *mpc;
in_cache_entry *in_entry;
eg_cache_entry *eg_entry;
-
+
mpc = find_mpc_by_lec(dev);
if (mpc == NULL) {
printk("mpoa: (%s) mpc_vcc_close: close for unknown MPC\n", dev->name);
struct mpoa_client *mpc;
__be32 tag;
char *tmp;
-
+
ddprintk("mpoa: (%s) mpc_push:\n", dev->name);
if (skb == NULL) {
dprintk("mpoa: (%s) mpc_push: null skb, closing VCC\n", dev->name);
mpc_vcc_close(vcc, dev);
return;
}
-
+
skb->dev = dev;
if (memcmp(skb->data, &llc_snap_mpoa_ctrl, sizeof(struct llc_snap_hdr)) == 0) {
struct sock *sk = sk_atm(vcc);
dev_kfree_skb_any(skb);
return;
}
-
+
/*
* See if ingress MPC is using shortcut we opened as a return channel.
* This means we have a bi-directional vcc opened by us.
- */
+ */
if (eg->shortcut == NULL) {
eg->shortcut = vcc;
printk("mpoa: (%s) mpc_push: egress SVC in use\n", dev->name);
struct mpoa_client *mpc;
struct lec_priv *priv;
int err;
-
+
if (mpcs == NULL) {
init_timer(&mpc_timer);
mpc_timer_refresh();
return err;
}
}
-
+
mpc = find_mpc_by_itfnum(arg);
if (mpc == NULL) {
dprintk("mpoa: mpoad_attach: allocating new mpc for itf %d\n", arg);
dev_put(mpc->dev);
mpc->dev = NULL;
} else
- priv->lane2_ops->associate_indicator = lane2_assoc_ind;
+ priv->lane2_ops->associate_indicator = lane2_assoc_ind;
}
mpc->mpoad_vcc = vcc;
if (mpc->dev) {
char empty[ATM_ESA_LEN];
memset(empty, 0, ATM_ESA_LEN);
-
+
start_mpc(mpc, mpc->dev);
/* set address if mpcd e.g. gets killed and restarted.
* If we do not do it now we have to wait for the next LE_ARP
struct k_message mesg;
memcpy (mpc->mps_ctrl_addr, addr, ATM_ESA_LEN);
-
+
mesg.type = SET_MPS_CTRL_ADDR;
memcpy(mesg.MPS_ctrl, addr, ATM_ESA_LEN);
msg_to_mpoad(&mesg, mpc);
printk("mpoa: mpoad_close: close for non-present mpoad\n");
return;
}
-
+
mpc->mpoad_vcc = NULL;
if (mpc->dev) {
struct lec_priv *priv = (struct lec_priv *)mpc->dev->priv;
atm_return(vcc, skb->truesize);
kfree_skb(skb);
}
-
+
printk("mpoa: (%s) going down\n",
(mpc->dev) ? mpc->dev->name : "<unknown>");
module_put(THIS_MODULE);
*/
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, &sk_atm(vcc)->sk_wmem_alloc);
-
+
if (mpc == NULL) {
printk("mpoa: msg_from_mpoad: no mpc found\n");
return 0;
skb_put(skb, sizeof(struct k_message));
memcpy(skb->data, mesg, sizeof(struct k_message));
atm_force_charge(mpc->mpoad_vcc, skb->truesize);
-
+
sk = sk_atm(mpc->mpoad_vcc);
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, skb->len);
dev = (struct net_device *)dev_ptr;
if (dev->name == NULL || strncmp(dev->name, "lec", 3))
return NOTIFY_DONE; /* we are only interested in lec:s */
-
+
switch (event) {
case NETDEV_REGISTER: /* a new lec device was allocated */
priv = (struct lec_priv *)dev->priv;
mpc->in_ops->put(entry);
return;
}
-
+
if(entry->entry_state == INGRESS_INVALID){
entry->entry_state = INGRESS_RESOLVING;
msg->type = SND_MPOA_RES_RQST;
mpc->in_ops->put(entry);
return;
}
-
+
printk("mpoa: (%s) MPOA_trigger_rcvd: entry already in resolving state\n",
(mpc->dev) ? mpc->dev->name : "<unknown>");
mpc->in_ops->put(entry);
/*
* Things get complicated because we have to check if there's an egress
- * shortcut with suitable traffic parameters we could use.
+ * shortcut with suitable traffic parameters we could use.
*/
static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_client *client, in_cache_entry *entry)
{
else if(eg_entry->shortcut->qos.txtp.max_pcr > 0)
entry->shortcut = eg_entry->shortcut;
}
- if(entry->shortcut){
+ if(entry->shortcut){
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;
{
msg->qos = qos->qos;
printk("mpoa: (%s) trying to get a CBR shortcut\n",client->dev->name);
- }
+ }
else memset(&msg->qos,0,sizeof(struct atm_qos));
msg_to_mpoad(msg, client);
return;
printk("\nmpoa: (%s) ARGH, received res. reply for an entry that doesn't exist.\n", mpc->dev->name);
return;
}
- ddprintk(" entry_state = %d ", entry->entry_state);
+ ddprintk(" entry_state = %d ", entry->entry_state);
if (entry->entry_state == INGRESS_RESOLVED) {
printk("\nmpoa: (%s) MPOA_res_reply_rcvd for RESOLVED entry!\n", mpc->dev->name);
ddprintk("entry->shortcut = %p\n", entry->shortcut);
if(entry->entry_state == INGRESS_RESOLVING && entry->shortcut != NULL){
- entry->entry_state = INGRESS_RESOLVED;
+ entry->entry_state = INGRESS_RESOLVED;
mpc->in_ops->put(entry);
return; /* Shortcut already open... */
}
mpc->in_ops->put(entry);
return;
}
-
+
check_qos_and_open_shortcut(msg, mpc, entry);
entry->entry_state = INGRESS_RESOLVED;
mpc->in_ops->put(entry);
} while (entry != NULL);
return;
-}
+}
static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
{
__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) {
dprintk("mpoa: (%s) egress_purge_rcvd: purge for a non-existing entry\n", mpc->dev->name);
return;
mpc->eg_ops->put(entry);
return;
-}
+}
static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry)
{
{
uint16_t holding_time;
eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(msg->content.eg_info.cache_id, mpc);
-
+
holding_time = msg->content.eg_info.holding_time;
dprintk("mpoa: (%s) MPOA_cache_impos_rcvd: entry = %p, holding_time = %u\n",
mpc->dev->name, entry, holding_time);
mpc->eg_ops->update(entry, holding_time);
return;
}
-
+
write_lock_irq(&mpc->egress_lock);
mpc->eg_ops->remove_entry(entry, mpc);
write_unlock_irq(&mpc->egress_lock);
mpc->eg_ops->put(entry);
-
+
return;
}
return;
}
client->number_of_mps_macs = 1;
-
+
return;
}
mpc_timer.data = mpc_timer.expires;
mpc_timer.function = mpc_cache_check;
add_timer(&mpc_timer);
-
+
return;
}
struct mpoa_client *mpc = mpcs;
static unsigned long previous_resolving_check_time;
static unsigned long previous_refresh_time;
-
+
while( mpc != NULL ){
mpc->in_ops->clear_count(mpc);
mpc->eg_ops->clear_expired(mpc);
mpc = mpc->next;
}
mpc_timer_refresh();
-
+
return;
}
int msg_to_mpoad(struct k_message *msg, struct mpoa_client *mpc);
struct mpoa_client {
- struct mpoa_client *next;
- struct net_device *dev; /* lec in question */
- int dev_num; /* e.g. 2 for lec2 */
- int (*old_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev);
- struct atm_vcc *mpoad_vcc; /* control channel to mpoad */
- uint8_t mps_ctrl_addr[ATM_ESA_LEN]; /* MPS control ATM address */
- uint8_t our_ctrl_addr[ATM_ESA_LEN]; /* MPC's control ATM address */
-
- rwlock_t ingress_lock;
- struct in_cache_ops *in_ops; /* ingress cache operations */
- in_cache_entry *in_cache; /* the ingress cache of this MPC */
-
- rwlock_t egress_lock;
- struct eg_cache_ops *eg_ops; /* egress cache operations */
- eg_cache_entry *eg_cache; /* the egress cache of this MPC */
-
- uint8_t *mps_macs; /* array of MPS MAC addresses, >=1 */
- int number_of_mps_macs; /* number of the above MAC addresses */
- struct mpc_parameters parameters; /* parameters for this client */
+ struct mpoa_client *next;
+ struct net_device *dev; /* lec in question */
+ int dev_num; /* e.g. 2 for lec2 */
+ int (*old_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev);
+ struct atm_vcc *mpoad_vcc; /* control channel to mpoad */
+ uint8_t mps_ctrl_addr[ATM_ESA_LEN]; /* MPS control ATM address */
+ uint8_t our_ctrl_addr[ATM_ESA_LEN]; /* MPC's control ATM address */
+
+ rwlock_t ingress_lock;
+ struct in_cache_ops *in_ops; /* ingress cache operations */
+ in_cache_entry *in_cache; /* the ingress cache of this MPC */
+
+ rwlock_t egress_lock;
+ struct eg_cache_ops *eg_ops; /* egress cache operations */
+ eg_cache_entry *eg_cache; /* the egress cache of this MPC */
+
+ uint8_t *mps_macs; /* array of MPS MAC addresses, >=1 */
+ int number_of_mps_macs; /* number of the above MAC addresses */
+ struct mpc_parameters parameters; /* parameters for this client */
};
struct atm_mpoa_qos {
- struct atm_mpoa_qos *next;
- __be32 ipaddr;
- struct atm_qos qos;
+ struct atm_mpoa_qos *next;
+ __be32 ipaddr;
+ struct atm_qos qos;
};
while (entry != NULL){
if (entry->shortcut == vcc) {
atomic_inc(&entry->use);
- read_unlock_irqrestore(&mpc->egress_lock, flags);
+ read_unlock_irqrestore(&mpc->egress_lock, flags);
return entry;
}
entry = entry->next;
while(entry != NULL){
if(entry->latest_ip_addr == ipaddr) {
atomic_inc(&entry->use);
- read_unlock_irq(&mpc->egress_lock);
+ read_unlock_irq(&mpc->egress_lock);
return entry;
}
entry = entry->next;
void atm_mpoa_init_cache(struct mpoa_client *mpc);
typedef struct in_cache_entry {
- struct in_cache_entry *next;
- struct in_cache_entry *prev;
- struct timeval tv;
- struct timeval reply_wait;
- struct timeval hold_down;
- uint32_t packets_fwded;
- uint16_t entry_state;
- uint32_t retry_time;
- uint32_t refresh_time;
- uint32_t count;
- struct atm_vcc *shortcut;
- uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
- struct in_ctrl_info ctrl_info;
- atomic_t use;
+ struct in_cache_entry *next;
+ struct in_cache_entry *prev;
+ struct timeval tv;
+ struct timeval reply_wait;
+ struct timeval hold_down;
+ uint32_t packets_fwded;
+ uint16_t entry_state;
+ uint32_t retry_time;
+ uint32_t refresh_time;
+ uint32_t count;
+ struct atm_vcc *shortcut;
+ uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
+ struct in_ctrl_info ctrl_info;
+ atomic_t use;
} in_cache_entry;
struct in_cache_ops{
- in_cache_entry *(*add_entry)(__be32 dst_ip,
- struct mpoa_client *client);
- in_cache_entry *(*get)(__be32 dst_ip, struct mpoa_client *client);
- in_cache_entry *(*get_with_mask)(__be32 dst_ip,
+ in_cache_entry *(*add_entry)(__be32 dst_ip,
+ struct mpoa_client *client);
+ in_cache_entry *(*get)(__be32 dst_ip, struct mpoa_client *client);
+ in_cache_entry *(*get_with_mask)(__be32 dst_ip,
struct mpoa_client *client,
__be32 mask);
- in_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc,
- struct mpoa_client *client);
- void (*put)(in_cache_entry *entry);
- void (*remove_entry)(in_cache_entry *delEntry,
+ in_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc,
+ struct mpoa_client *client);
+ void (*put)(in_cache_entry *entry);
+ void (*remove_entry)(in_cache_entry *delEntry,
struct mpoa_client *client );
- int (*cache_hit)(in_cache_entry *entry,
- struct mpoa_client *client);
- void (*clear_count)(struct mpoa_client *client);
- void (*check_resolving)(struct mpoa_client *client);
- void (*refresh)(struct mpoa_client *client);
- void (*destroy_cache)(struct mpoa_client *mpc);
+ int (*cache_hit)(in_cache_entry *entry,
+ struct mpoa_client *client);
+ void (*clear_count)(struct mpoa_client *client);
+ void (*check_resolving)(struct mpoa_client *client);
+ void (*refresh)(struct mpoa_client *client);
+ void (*destroy_cache)(struct mpoa_client *mpc);
};
typedef struct eg_cache_entry{
- struct eg_cache_entry *next;
- struct eg_cache_entry *prev;
- struct timeval tv;
- uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
- struct atm_vcc *shortcut;
- uint32_t packets_rcvd;
- uint16_t entry_state;
- __be32 latest_ip_addr; /* The src IP address of the last packet */
- struct eg_ctrl_info ctrl_info;
- atomic_t use;
+ struct eg_cache_entry *next;
+ struct eg_cache_entry *prev;
+ struct timeval tv;
+ uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
+ struct atm_vcc *shortcut;
+ uint32_t packets_rcvd;
+ uint16_t entry_state;
+ __be32 latest_ip_addr; /* The src IP address of the last packet */
+ struct eg_ctrl_info ctrl_info;
+ atomic_t use;
} eg_cache_entry;
struct eg_cache_ops{
- eg_cache_entry *(*add_entry)(struct k_message *msg, struct mpoa_client *client);
- eg_cache_entry *(*get_by_cache_id)(__be32 cache_id, struct mpoa_client *client);
- eg_cache_entry *(*get_by_tag)(__be32 cache_id, struct mpoa_client *client);
- eg_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc, struct mpoa_client *client);
- eg_cache_entry *(*get_by_src_ip)(__be32 ipaddr, struct mpoa_client *client);
- void (*put)(eg_cache_entry *entry);
- void (*remove_entry)(eg_cache_entry *entry, struct mpoa_client *client);
- void (*update)(eg_cache_entry *entry, uint16_t holding_time);
- void (*clear_expired)(struct mpoa_client *client);
- void (*destroy_cache)(struct mpoa_client *mpc);
+ eg_cache_entry *(*add_entry)(struct k_message *msg, struct mpoa_client *client);
+ eg_cache_entry *(*get_by_cache_id)(__be32 cache_id, struct mpoa_client *client);
+ eg_cache_entry *(*get_by_tag)(__be32 cache_id, struct mpoa_client *client);
+ eg_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc, struct mpoa_client *client);
+ eg_cache_entry *(*get_by_src_ip)(__be32 ipaddr, struct mpoa_client *client);
+ void (*put)(eg_cache_entry *entry);
+ void (*remove_entry)(eg_cache_entry *entry, struct mpoa_client *client);
+ void (*update)(eg_cache_entry *entry, uint16_t holding_time);
+ void (*clear_expired)(struct mpoa_client *client);
+ void (*destroy_cache)(struct mpoa_client *mpc);
};
/* VCC states */
#define OPEN 1
-#define CLOSED 0
+#define CLOSED 0
/* Egress cache entry states */
#ifdef CONFIG_PROC_FS
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/string.h>
+#include <linux/string.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
/*
* mpoa_proc.c: Implementation MPOA client's proc
- * file system statistics
+ * file system statistics
*/
#if 1
static int proc_mpc_open(struct inode *inode, struct file *file);
static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
- size_t nbytes, loff_t *ppos);
+ size_t nbytes, loff_t *ppos);
static int parse_qos(const char *buff);
* Returns the state of an ingress cache entry as a string
*/
static const char *ingress_state_string(int state){
- switch(state) {
+ switch(state) {
case INGRESS_RESOLVING:
- return "resolving ";
+ return "resolving ";
break;
case INGRESS_RESOLVED:
- return "resolved ";
+ return "resolved ";
break;
case INGRESS_INVALID:
- return "invalid ";
+ return "invalid ";
break;
case INGRESS_REFRESHING:
- return "refreshing ";
+ return "refreshing ";
break;
default:
return "";
* Returns the state of an egress cache entry as a string
*/
static const char *egress_state_string(int state){
- switch(state) {
+ switch(state) {
case EGRESS_RESOLVED:
- return "resolved ";
+ return "resolved ";
break;
case EGRESS_PURGE:
- return "purge ";
+ return "purge ";
break;
case EGRESS_INVALID:
- return "invalid ";
+ return "invalid ";
break;
default:
return "";
return 0;
}
- seq_printf(m, "\nInterface %d:\n\n", mpc->dev_num);
+ seq_printf(m, "\nInterface %d:\n\n", mpc->dev_num);
seq_printf(m, "Ingress Entries:\nIP address State Holding time Packets fwded VPI VCI\n");
do_gettimeofday(&now);
egress_state_string(eg_entry->entry_state),
(eg_entry->ctrl_info.holding_time-(now.tv_sec-eg_entry->tv.tv_sec)),
eg_entry->packets_rcvd);
-
+
/* latest IP address */
temp = (unsigned char *)&eg_entry->latest_ip_addr;
sprintf(ip_string, "%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
}
static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
- size_t nbytes, loff_t *ppos)
+ size_t nbytes, loff_t *ppos)
{
- char *page, *p;
+ char *page, *p;
unsigned len;
- if (nbytes == 0)
+ if (nbytes == 0)
return 0;
- if (nbytes >= PAGE_SIZE)
+ if (nbytes >= PAGE_SIZE)
nbytes = PAGE_SIZE-1;
- page = (char *)__get_free_page(GFP_KERNEL);
- if (!page)
+ page = (char *)__get_free_page(GFP_KERNEL);
+ if (!page)
return -ENOMEM;
- for (p = page, len = 0; len < nbytes; p++, len++) {
- if (get_user(*p, buff++)) {
+ for (p = page, len = 0; len < nbytes; p++, len++) {
+ if (get_user(*p, buff++)) {
free_page((unsigned long)page);
return -EFAULT;
}
- if (*p == '\0' || *p == '\n')
- break;
- }
+ if (*p == '\0' || *p == '\n')
+ break;
+ }
- *p = '\0';
+ *p = '\0';
if (!parse_qos(page))
- printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
+ printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
+
+ free_page((unsigned long)page);
- free_page((unsigned long)page);
-
- return len;
+ return len;
}
static int parse_qos(const char *buff)
{
- /* possible lines look like this
- * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
- */
- unsigned char ip[4];
+ /* possible lines look like this
+ * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
+ */
+ unsigned char ip[4];
int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
- __be32 ipaddr;
- struct atm_qos qos;
-
- memset(&qos, 0, sizeof(struct atm_qos));
+ __be32 ipaddr;
+ struct atm_qos qos;
+
+ memset(&qos, 0, sizeof(struct atm_qos));
if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
ip, ip+1, ip+2, ip+3) == 4) {
ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8)
return 0;
- ipaddr = *(__be32 *)ip;
+ ipaddr = *(__be32 *)ip;
qos.txtp.traffic_class = ATM_CBR;
qos.txtp.max_pcr = tx_pcr;
qos.txtp.max_sdu = tx_sdu;
qos.rxtp.traffic_class = ATM_CBR;
qos.rxtp.max_pcr = rx_pcr;
qos.rxtp.max_sdu = rx_sdu;
- qos.aal = ATM_AAL5;
+ qos.aal = ATM_AAL5;
dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
qos.txtp.max_pcr,
qos.txtp.max_sdu,
{
struct proc_dir_entry *p;
- p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
+ p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
if (!p) {
- printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
- return -ENOMEM;
- }
+ printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
+ return -ENOMEM;
+ }
p->proc_fops = &mpc_file_operations;
p->owner = THIS_MODULE;
return 0;
break;
}
l--;
- }
+ }
try_again:
for (; sk; sk = sk_next(sk)) {
l -= compare_family(sk, family);
seq_printf(seq, "%p ", vcc);
if (!vcc->dev)
seq_printf(seq, "Unassigned ");
- else
+ else
seq_printf(seq, "%3d %3d %5d ", vcc->dev->number, vcc->vpi,
vcc->vci);
switch (sk->sk_family) {
static char atm_dev_banner[] =
"Itf Type ESI/\"MAC\"addr "
"AAL(TX,err,RX,err,drop) ... [refcnt]\n";
-
+
if (v == (void *)1)
seq_puts(seq, atm_dev_banner);
else {
atm_dev_info(seq, dev);
}
- return 0;
+ return 0;
}
-
+
static struct seq_operations atm_dev_seq_ops = {
.start = atm_dev_seq_start,
.next = atm_dev_seq_next,
.stop = atm_dev_seq_stop,
.show = atm_dev_seq_show,
};
-
+
static int atm_dev_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &atm_dev_seq_ops);
}
-
+
static struct file_operations devices_seq_fops = {
.open = atm_dev_seq_open,
.read = seq_read,
static int pvc_seq_show(struct seq_file *seq, void *v)
{
- static char atm_pvc_banner[] =
+ static char atm_pvc_banner[] =
"Itf VPI VCI AAL RX(PCR,Class) TX(PCR,Class)\n";
if (v == (void *)1)
static int vcc_seq_show(struct seq_file *seq, void *v)
{
- if (v == (void *)1) {
- seq_printf(seq, sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s",
- "Address ", "Itf VPI VCI Fam Flags Reply "
- "Send buffer Recv buffer [refcnt]\n");
- } else {
- struct vcc_state *state = seq->private;
- struct atm_vcc *vcc = atm_sk(state->sk);
-
- vcc_info(seq, vcc);
- }
- return 0;
+ if (v == (void *)1) {
+ seq_printf(seq, sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s",
+ "Address ", "Itf VPI VCI Fam Flags Reply "
+ "Send buffer Recv buffer [refcnt]\n");
+ } else {
+ struct vcc_state *state = seq->private;
+ struct atm_vcc *vcc = atm_sk(state->sk);
+
+ vcc_info(seq, vcc);
+ }
+ return 0;
}
-
+
static struct seq_operations vcc_seq_ops = {
- .start = vcc_seq_start,
- .next = vcc_seq_next,
- .stop = vcc_seq_stop,
- .show = vcc_seq_show,
+ .start = vcc_seq_start,
+ .next = vcc_seq_next,
+ .stop = vcc_seq_stop,
+ .show = vcc_seq_show,
};
-
+
static int vcc_seq_open(struct inode *inode, struct file *file)
{
- return __vcc_seq_open(inode, file, 0, &vcc_seq_ops);
+ return __vcc_seq_open(inode, file, 0, &vcc_seq_ops);
}
-
+
static struct file_operations vcc_seq_fops = {
.open = vcc_seq_open,
.read = seq_read,
static int svc_seq_show(struct seq_file *seq, void *v)
{
- static char atm_svc_banner[] =
+ static char atm_svc_banner[] =
"Itf VPI VCI State Remote\n";
if (v == (void *)1)
static struct atm_proc_entry *e;
for (e = atm_proc_ents; e->name; e++) {
- if (e->dirent)
+ if (e->dirent)
remove_proc_entry(e->name, atm_proc_root);
}
remove_proc_entry("net/atm", NULL);
static int pvc_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
int error;
struct atm_vcc *vcc = ATM_SD(sock);
if (!vcc->dev || !test_bit(ATM_VF_ADDR,&vcc->flags)) return -ENOTCONN;
- *sockaddr_len = sizeof(struct sockaddr_atmpvc);
+ *sockaddr_len = sizeof(struct sockaddr_atmpvc);
addr = (struct sockaddr_atmpvc *) sockaddr;
addr->sap_family = AF_ATMPVC;
addr->sap_addr.itf = vcc->dev->number;
* still work
*/
if (!capable(CAP_NET_ADMIN) &&
- (((u32 *) skb->data)[0] & (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)) !=
- ((vcc->vpi << ATM_HDR_VPI_SHIFT) | (vcc->vci << ATM_HDR_VCI_SHIFT)))
+ (((u32 *) skb->data)[0] & (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)) !=
+ ((vcc->vpi << ATM_HDR_VPI_SHIFT) | (vcc->vci << ATM_HDR_VCI_SHIFT)))
{
kfree_skb(skb);
return -EADDRNOTAVAIL;
- }
+ }
return vcc->dev->ops->send(vcc,skb);
}
set_bit(ATM_DF_REMOVED, &dev->flags);
/*
- * if we remove current device from atm_devs list, new device
- * with same number can appear, such we need deregister proc,
+ * if we remove current device from atm_devs list, new device
+ * with same number can appear, such we need deregister proc,
* release async all vccs and remove them from vccs list too
*/
mutex_lock(&atm_dev_mutex);
*tmp_p++ = dev->number;
}
mutex_unlock(&atm_dev_mutex);
- error = ((copy_to_user(buf, tmp_buf, size)) ||
+ error = ((copy_to_user(buf, tmp_buf, size)) ||
put_user(size, &iobuf->length))
? -EFAULT : 0;
kfree(tmp_buf);
if (!(dev = try_then_request_module(atm_dev_lookup(number),
"atm-device-%d", number)))
return -ENODEV;
-
+
switch (cmd) {
case ATM_GETTYPE:
size = strlen(dev->type) + 1;
goto done;
}
}
-
+
if (size)
error = put_user(size, &sioc->length)
? -EFAULT : 0;
void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
{
- mutex_lock(&atm_dev_mutex);
+ mutex_lock(&atm_dev_mutex);
return *pos ? dev_get_idx(*pos) : (void *) 1;
}
void atm_dev_seq_stop(struct seq_file *seq, void *v)
{
- mutex_unlock(&atm_dev_mutex);
+ mutex_unlock(&atm_dev_mutex);
}
-
+
void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
++*pos;
/* net/atm/signaling.h - ATM signaling */
-
+
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
+
#ifndef NET_ATM_SIGNALING_H
#define NET_ATM_SIGNALING_H
clear_bit(ATM_VF_READY, &vcc->flags);
/* VCC pointer is used as a reference, so we must not free it
(thereby subjecting it to re-use) before all pending connections
- are closed */
+ are closed */
svc_disconnect(vcc);
vcc_release(sock);
}
error = -EUNATCH;
goto out;
}
- if (!sk->sk_err)
+ if (!sk->sk_err)
set_bit(ATM_VF_BOUND,&vcc->flags);
error = -sk->sk_err;
out:
* This is tricky:
* Kernel ---close--> Demon
* Kernel <--close--- Demon
- * or
+ * or
* Kernel ---close--> Demon
* Kernel <--error--- Demon
* or
}
set_bit(ATM_VF_HASSAP, &vcc->flags);
break;
- case SO_MULTIPOINT:
+ case SO_MULTIPOINT:
if (level != SOL_ATM || optlen != sizeof(int)) {
error = -EINVAL;
goto out;
}
- if (get_user(value, (int __user *) optval)) {
- error = -EFAULT;
+ if (get_user(value, (int __user *) optval)) {
+ error = -EFAULT;
goto out;
}
if (value == 1) {
} else {
error = -EINVAL;
}
- break;
+ break;
default:
error = vcc_setsockopt(sock, level, optname,
optval, optlen);
set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
sigd_enq(vcc, as_addparty, NULL, NULL,
- (struct sockaddr_atmsvc *) sockaddr);
+ (struct sockaddr_atmsvc *) sockaddr);
if (flags & O_NONBLOCK) {
finish_wait(sk->sk_sleep, &wait);
error = -EINPROGRESS;
static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
- int error, ep_ref;
- struct sockaddr_atmsvc sa;
+ int error, ep_ref;
+ struct sockaddr_atmsvc sa;
struct atm_vcc *vcc = ATM_SD(sock);
-
+
switch (cmd) {
- case ATM_ADDPARTY:
- if (!test_bit(ATM_VF_SESSION, &vcc->flags))
- return -EINVAL;
- if (copy_from_user(&sa, (void __user *) arg, sizeof(sa)))
+ case ATM_ADDPARTY:
+ if (!test_bit(ATM_VF_SESSION, &vcc->flags))
+ return -EINVAL;
+ if (copy_from_user(&sa, (void __user *) arg, sizeof(sa)))
return -EFAULT;
- error = svc_addparty(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
- break;
- case ATM_DROPPARTY:
- if (!test_bit(ATM_VF_SESSION, &vcc->flags))
- return -EINVAL;
- if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int)))
+ error = svc_addparty(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
+ break;
+ case ATM_DROPPARTY:
+ if (!test_bit(ATM_VF_SESSION, &vcc->flags))
+ return -EINVAL;
+ if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int)))
return -EFAULT;
- error = svc_dropparty(sock, ep_ref);
- break;
- default:
+ error = svc_dropparty(sock, ep_ref);
+ break;
+ default:
error = vcc_ioctl(sock, cmd, arg);
}