Lines Matching +full:vcc +full:- +full:p
1 /* net/atm/clip.c - RFC1577 Classical IP over ATM */
3 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
59 return -EUNATCH; in to_atmarpd()
62 return -ENOMEM; in to_atmarpd()
64 ctrl->type = type; in to_atmarpd()
65 ctrl->itf_num = itf; in to_atmarpd()
66 ctrl->ip = ip; in to_atmarpd()
67 atm_force_charge(atmarpd, skb->truesize); in to_atmarpd()
70 skb_queue_tail(&sk->sk_receive_queue, skb); in to_atmarpd()
71 sk->sk_data_ready(sk); in to_atmarpd()
77 pr_debug("%p to entry %p (neigh %p)\n", clip_vcc, entry, entry->neigh); in link_vcc()
78 clip_vcc->entry = entry; in link_vcc()
79 clip_vcc->xoff = 0; /* @@@ may overrun buffer by one packet */ in link_vcc()
80 clip_vcc->next = entry->vccs; in link_vcc()
81 entry->vccs = clip_vcc; in link_vcc()
82 entry->neigh->used = jiffies; in link_vcc()
87 struct atmarp_entry *entry = clip_vcc->entry; in unlink_clip_vcc()
91 pr_crit("!clip_vcc->entry (clip_vcc %p)\n", clip_vcc); in unlink_clip_vcc()
94 netif_tx_lock_bh(entry->neigh->dev); /* block clip_start_xmit() */ in unlink_clip_vcc()
95 entry->neigh->used = jiffies; in unlink_clip_vcc()
96 for (walk = &entry->vccs; *walk; walk = &(*walk)->next) in unlink_clip_vcc()
100 *walk = clip_vcc->next; /* atomic */ in unlink_clip_vcc()
101 clip_vcc->entry = NULL; in unlink_clip_vcc()
102 if (clip_vcc->xoff) in unlink_clip_vcc()
103 netif_wake_queue(entry->neigh->dev); in unlink_clip_vcc()
104 if (entry->vccs) in unlink_clip_vcc()
106 entry->expires = jiffies - 1; in unlink_clip_vcc()
108 error = neigh_update(entry->neigh, NULL, NUD_NONE, in unlink_clip_vcc()
114 pr_crit("ATMARP: failed (entry %p, vcc 0x%p)\n", entry, clip_vcc); in unlink_clip_vcc()
116 netif_tx_unlock_bh(entry->neigh->dev); in unlink_clip_vcc()
119 /* The neighbour entry n->lock is held. */
125 if (n->ops != &clip_neigh_ops) in neigh_check_cb()
127 for (cv = entry->vccs; cv; cv = cv->next) { in neigh_check_cb()
128 unsigned long exp = cv->last_use + cv->idle_timeout; in neigh_check_cb()
130 if (cv->idle_timeout && time_after(jiffies, exp)) { in neigh_check_cb()
131 pr_debug("releasing vcc %p->%p of entry %p\n", in neigh_check_cb()
132 cv, cv->vcc, entry); in neigh_check_cb()
133 vcc_release_async(cv->vcc, -ETIMEDOUT); in neigh_check_cb()
137 if (entry->vccs || time_before(jiffies, entry->expires)) in neigh_check_cb()
140 if (refcount_read(&n->refcnt) > 1) { in neigh_check_cb()
144 refcount_read(&n->refcnt)); in neigh_check_cb()
146 while ((skb = skb_dequeue(&n->arp_queue)) != NULL) in neigh_check_cb()
152 pr_debug("expired neigh %p\n", n); in neigh_check_cb()
166 struct atm_vcc *vcc; in clip_arp_rcv() local
169 vcc = ATM_SKB(skb)->vcc; in clip_arp_rcv()
170 if (!vcc || !atm_charge(vcc, skb->truesize)) { in clip_arp_rcv()
174 pr_debug("pushing to %p\n", vcc); in clip_arp_rcv()
175 pr_debug("using %p\n", CLIP_VCC(vcc)->old_push); in clip_arp_rcv()
176 CLIP_VCC(vcc)->old_push(vcc, skb); in clip_arp_rcv()
181 0xaa, /* DSAP: non-ISO */
182 0xaa, /* SSAP: non-ISO */
189 static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) in clip_push() argument
191 struct clip_vcc *clip_vcc = CLIP_VCC(vcc); in clip_push()
196 atm_return(vcc, skb->truesize); in clip_push()
202 pr_debug("removing VCC %p\n", clip_vcc); in clip_push()
203 if (clip_vcc->entry) in clip_push()
205 clip_vcc->old_push(vcc, NULL); /* pass on the bad news */ in clip_push()
209 atm_return(vcc, skb->truesize); in clip_push()
210 skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs; in clip_push()
211 /* clip_vcc->entry == NULL if we don't have an IP address yet */ in clip_push()
212 if (!skb->dev) { in clip_push()
216 ATM_SKB(skb)->vcc = vcc; in clip_push()
218 if (!clip_vcc->encap || in clip_push()
219 skb->len < RFC1483LLC_LEN || in clip_push()
220 memcmp(skb->data, llc_oui, sizeof(llc_oui))) in clip_push()
221 skb->protocol = htons(ETH_P_IP); in clip_push()
223 skb->protocol = ((__be16 *)skb->data)[3]; in clip_push()
225 if (skb->protocol == htons(ETH_P_ARP)) { in clip_push()
226 skb->dev->stats.rx_packets++; in clip_push()
227 skb->dev->stats.rx_bytes += skb->len; in clip_push()
232 clip_vcc->last_use = jiffies; in clip_push()
233 skb->dev->stats.rx_packets++; in clip_push()
234 skb->dev->stats.rx_bytes += skb->len; in clip_push()
240 * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
244 static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb) in clip_pop() argument
246 struct clip_vcc *clip_vcc = CLIP_VCC(vcc); in clip_pop()
247 struct net_device *dev = skb->dev; in clip_pop()
251 pr_debug("(vcc %p)\n", vcc); in clip_pop()
252 clip_vcc->old_pop(vcc, skb); in clip_pop()
253 /* skb->dev == NULL in outbound ARP packets */ in clip_pop()
256 spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags); in clip_pop()
257 if (atm_may_send(vcc, 0)) { in clip_pop()
258 old = xchg(&clip_vcc->xoff, 0); in clip_pop()
262 spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); in clip_pop()
267 __be32 *ip = (__be32 *) neigh->primary_key; in clip_neigh_solicit()
269 pr_debug("(neigh %p, skb %p)\n", neigh, skb); in clip_neigh_solicit()
270 to_atmarpd(act_need, PRIV(neigh->dev)->number, *ip); in clip_neigh_solicit()
293 if (neigh->tbl->family != AF_INET) in clip_constructor()
294 return -EINVAL; in clip_constructor()
296 if (neigh->type != RTN_UNICAST) in clip_constructor()
297 return -EINVAL; in clip_constructor()
299 neigh->nud_state = NUD_NONE; in clip_constructor()
300 neigh->ops = &clip_neigh_ops; in clip_constructor()
301 neigh->output = neigh->ops->output; in clip_constructor()
302 entry->neigh = neigh; in clip_constructor()
303 entry->vccs = NULL; in clip_constructor()
304 entry->expires = jiffies - 1; in clip_constructor()
309 /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
312 * We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
318 static int clip_encap(struct atm_vcc *vcc, int mode) in clip_encap() argument
320 if (!CLIP_VCC(vcc)) in clip_encap()
321 return -EBADFD; in clip_encap()
323 CLIP_VCC(vcc)->encap = mode; in clip_encap()
334 struct atm_vcc *vcc; in clip_start_xmit() local
340 pr_debug("(skb %p)\n", skb); in clip_start_xmit()
344 dev->stats.tx_dropped++; in clip_start_xmit()
348 if (rt->rt_gateway) in clip_start_xmit()
349 daddr = &rt->rt_gateway; in clip_start_xmit()
351 daddr = &ip_hdr(skb)->daddr; in clip_start_xmit()
356 dev->stats.tx_dropped++; in clip_start_xmit()
360 if (!entry->vccs) { in clip_start_xmit()
361 if (time_after(jiffies, entry->expires)) { in clip_start_xmit()
363 entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ; in clip_start_xmit()
364 to_atmarpd(act_need, PRIV(dev)->number, *((__be32 *)n->primary_key)); in clip_start_xmit()
366 if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS) in clip_start_xmit()
367 skb_queue_tail(&entry->neigh->arp_queue, skb); in clip_start_xmit()
370 dev->stats.tx_dropped++; in clip_start_xmit()
374 pr_debug("neigh %p, vccs %p\n", entry, entry->vccs); in clip_start_xmit()
375 ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc; in clip_start_xmit()
376 pr_debug("using neighbour %p, vcc %p\n", n, vcc); in clip_start_xmit()
377 if (entry->vccs->encap) { in clip_start_xmit()
382 ((__be16 *) here)[3] = skb->protocol; in clip_start_xmit()
384 atm_account_tx(vcc, skb); in clip_start_xmit()
385 entry->vccs->last_use = jiffies; in clip_start_xmit()
386 pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev); in clip_start_xmit()
387 old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */ in clip_start_xmit()
389 pr_warn("XOFF->XOFF transition\n"); in clip_start_xmit()
392 dev->stats.tx_packets++; in clip_start_xmit()
393 dev->stats.tx_bytes += skb->len; in clip_start_xmit()
394 vcc->send(vcc, skb); in clip_start_xmit()
395 if (atm_may_send(vcc, 0)) { in clip_start_xmit()
396 entry->vccs->xoff = 0; in clip_start_xmit()
399 spin_lock_irqsave(&clip_priv->xoff_lock, flags); in clip_start_xmit()
400 netif_stop_queue(dev); /* XOFF -> throttle immediately */ in clip_start_xmit()
402 if (!entry->vccs->xoff) in clip_start_xmit()
408 spin_unlock_irqrestore(&clip_priv->xoff_lock, flags); in clip_start_xmit()
414 static int clip_mkip(struct atm_vcc *vcc, int timeout) in clip_mkip() argument
418 if (!vcc->push) in clip_mkip()
419 return -EBADFD; in clip_mkip()
422 return -ENOMEM; in clip_mkip()
423 pr_debug("%p vcc %p\n", clip_vcc, vcc); in clip_mkip()
424 clip_vcc->vcc = vcc; in clip_mkip()
425 vcc->user_back = clip_vcc; in clip_mkip()
426 set_bit(ATM_VF_IS_CLIP, &vcc->flags); in clip_mkip()
427 clip_vcc->entry = NULL; in clip_mkip()
428 clip_vcc->xoff = 0; in clip_mkip()
429 clip_vcc->encap = 1; in clip_mkip()
430 clip_vcc->last_use = jiffies; in clip_mkip()
431 clip_vcc->idle_timeout = timeout * HZ; in clip_mkip()
432 clip_vcc->old_push = vcc->push; in clip_mkip()
433 clip_vcc->old_pop = vcc->pop; in clip_mkip()
434 vcc->push = clip_push; in clip_mkip()
435 vcc->pop = clip_pop; in clip_mkip()
437 /* re-process everything received between connection setup and MKIP */ in clip_mkip()
438 vcc_process_recv_queue(vcc); in clip_mkip()
443 static int clip_setentry(struct atm_vcc *vcc, __be32 ip) in clip_setentry() argument
451 if (vcc->push != clip_push) { in clip_setentry()
452 pr_warn("non-CLIP VCC\n"); in clip_setentry()
453 return -EBADF; in clip_setentry()
455 clip_vcc = CLIP_VCC(vcc); in clip_setentry()
457 if (!clip_vcc->entry) { in clip_setentry()
468 neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1); in clip_setentry()
471 return -ENOMEM; in clip_setentry()
473 if (entry != clip_vcc->entry) { in clip_setentry()
474 if (!clip_vcc->entry) in clip_setentry()
495 dev->netdev_ops = &clip_netdev_ops; in clip_setup()
496 dev->type = ARPHRD_ATM; in clip_setup()
497 dev->neigh_priv_len = sizeof(struct atmarp_entry); in clip_setup()
498 dev->hard_header_len = RFC1483LLC_LEN; in clip_setup()
499 dev->mtu = RFC1626_MTU; in clip_setup()
500 dev->tx_queue_len = 100; /* "normal" queue (packets) */ in clip_setup()
504 /* compromise between decent burst-tolerance and protection */ in clip_setup()
515 if (number != -1) { in clip_create()
516 for (dev = clip_devs; dev; dev = PRIV(dev)->next) in clip_create()
517 if (PRIV(dev)->number == number) in clip_create()
518 return -EEXIST; in clip_create()
521 for (dev = clip_devs; dev; dev = PRIV(dev)->next) in clip_create()
522 if (PRIV(dev)->number >= number) in clip_create()
523 number = PRIV(dev)->number + 1; in clip_create()
528 return -ENOMEM; in clip_create()
530 sprintf(dev->name, "atm%d", number); in clip_create()
531 spin_lock_init(&clip_priv->xoff_lock); in clip_create()
532 clip_priv->number = number; in clip_create()
538 clip_priv->next = clip_devs; in clip_create()
540 pr_debug("registered (net:%s)\n", dev->name); in clip_create()
555 /* ignore non-CLIP devices */ in clip_device_event()
556 if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops) in clip_device_event()
562 to_atmarpd(act_up, PRIV(dev)->number, 0); in clip_device_event()
566 to_atmarpd(act_down, PRIV(dev)->number, 0); in clip_device_event()
571 to_atmarpd(act_change, PRIV(dev)->number, 0); in clip_device_event()
583 in_dev = ((struct in_ifaddr *)ifa)->ifa_dev; in clip_inet_event()
585 * Transitions are of the down-change-up type, so it's sufficient to in clip_inet_event()
590 netdev_notifier_info_init(&info, in_dev->dev); in clip_inet_event()
606 static void atmarpd_close(struct atm_vcc *vcc) in atmarpd_close() argument
612 skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); in atmarpd_close()
632 static int atm_init_atmarp(struct atm_vcc *vcc) in atm_init_atmarp() argument
637 return -EADDRINUSE; in atm_init_atmarp()
642 atmarpd = vcc; in atm_init_atmarp()
643 set_bit(ATM_VF_META, &vcc->flags); in atm_init_atmarp()
644 set_bit(ATM_VF_READY, &vcc->flags); in atm_init_atmarp()
646 vcc->dev = &atmarpd_dev; in atm_init_atmarp()
647 vcc_insert_socket(sk_atm(vcc)); in atm_init_atmarp()
648 vcc->push = NULL; in atm_init_atmarp()
649 vcc->pop = NULL; /* crash */ in atm_init_atmarp()
650 vcc->push_oam = NULL; /* crash */ in atm_init_atmarp()
657 struct atm_vcc *vcc = ATM_SD(sock); in clip_ioctl() local
667 return -EPERM; in clip_ioctl()
670 return -ENOIOCTLCMD; in clip_ioctl()
678 err = atm_init_atmarp(vcc); in clip_ioctl()
680 sock->state = SS_CONNECTED; in clip_ioctl()
685 err = clip_mkip(vcc, arg); in clip_ioctl()
688 err = clip_setentry(vcc, (__force __be32)arg); in clip_ioctl()
691 err = clip_encap(vcc, arg); in clip_ioctl()
709 if (*addr->sas_addr.pub) { in svc_addr()
710 seq_printf(seq, "%s", addr->sas_addr.pub); in svc_addr()
711 if (*addr->sas_addr.prv) in svc_addr()
713 } else if (!*addr->sas_addr.prv) { in svc_addr()
717 if (*addr->sas_addr.prv) { in svc_addr()
718 unsigned char *prv = addr->sas_addr.prv; in svc_addr()
724 for (j = fields[i]; j; j--) in svc_addr()
732 /* This means the neighbour entry has no attached VCC objects. */
738 struct net_device *dev = n->dev; in atmarp_info()
744 (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC)); in atmarp_info()
746 llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap); in atmarp_info()
749 exp = entry->neigh->used; in atmarp_info()
751 exp = clip_vcc->last_use; in atmarp_info()
753 exp = (jiffies - exp) / HZ; in atmarp_info()
755 seq_printf(seq, "%-6s%-4s%-4s%5ld ", in atmarp_info()
756 dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp); in atmarp_info()
758 off = scnprintf(buf, sizeof(buf) - 1, "%pI4", n->primary_key); in atmarp_info()
765 if (time_before(jiffies, entry->expires)) in atmarp_info()
769 refcount_read(&entry->neigh->refcnt)); in atmarp_info()
772 clip_vcc->vcc->dev->number, in atmarp_info()
773 clip_vcc->vcc->vpi, clip_vcc->vcc->vci); in atmarp_info()
775 svc_addr(seq, &clip_vcc->vcc->remote); in atmarp_info()
785 struct clip_vcc *vcc; member
792 curr = e->vccs; in clip_seq_next_vcc()
800 curr = curr->next; in clip_seq_next_vcc()
808 struct clip_vcc *vcc = state->vcc; in clip_seq_vcc_walk() local
810 vcc = clip_seq_next_vcc(e, vcc); in clip_seq_vcc_walk()
811 if (vcc && pos != NULL) { in clip_seq_vcc_walk()
813 vcc = clip_seq_next_vcc(e, vcc); in clip_seq_vcc_walk()
814 if (!vcc) in clip_seq_vcc_walk()
816 --(*pos); in clip_seq_vcc_walk()
819 state->vcc = vcc; in clip_seq_vcc_walk()
821 return vcc; in clip_seq_vcc_walk()
829 if (n->dev->type != ARPHRD_ATM) in clip_seq_sub_iter()
837 struct clip_seq_state *state = seq->private; in clip_seq_start()
838 state->ns.neigh_sub_iter = clip_seq_sub_iter; in clip_seq_start()
850 struct clip_seq_state *state = seq->private; in clip_seq_show()
851 struct clip_vcc *vcc = state->vcc; in clip_seq_show() local
854 atmarp_info(seq, n, neighbour_priv(n), vcc); in clip_seq_show()
879 struct proc_dir_entry *p; in atm_clip_init() local
881 p = proc_create_net("arp", 0444, atm_proc_root, &arp_seq_ops, in atm_clip_init()
883 if (!p) { in atm_clip_init()
886 return -ENOMEM; in atm_clip_init()
910 next = PRIV(dev)->next; in atm_clip_exit_noproc()