Lines Matching +full:vcc +full:- +full:p
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* net/atm/clip.c - RFC1577 Classical IP over ATM */
4 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
57 struct atm_vcc *vcc; in to_atmarpd() local
64 vcc = rcu_dereference(atmarpd); in to_atmarpd()
65 if (!vcc) { in to_atmarpd()
66 err = -EUNATCH; in to_atmarpd()
71 err = -ENOMEM; in to_atmarpd()
75 ctrl->type = type; in to_atmarpd()
76 ctrl->itf_num = itf; in to_atmarpd()
77 ctrl->ip = ip; in to_atmarpd()
78 atm_force_charge(vcc, skb->truesize); in to_atmarpd()
80 sk = sk_atm(vcc); in to_atmarpd()
81 skb_queue_tail(&sk->sk_receive_queue, skb); in to_atmarpd()
82 sk->sk_data_ready(sk); in to_atmarpd()
90 pr_debug("%p to entry %p (neigh %p)\n", clip_vcc, entry, entry->neigh); in link_vcc()
91 clip_vcc->entry = entry; in link_vcc()
92 clip_vcc->xoff = 0; /* @@@ may overrun buffer by one packet */ in link_vcc()
93 clip_vcc->next = entry->vccs; in link_vcc()
94 entry->vccs = clip_vcc; in link_vcc()
95 entry->neigh->used = jiffies; in link_vcc()
100 struct atmarp_entry *entry = clip_vcc->entry; in unlink_clip_vcc()
104 pr_err("!clip_vcc->entry (clip_vcc %p)\n", clip_vcc); in unlink_clip_vcc()
107 netif_tx_lock_bh(entry->neigh->dev); /* block clip_start_xmit() */ in unlink_clip_vcc()
108 entry->neigh->used = jiffies; in unlink_clip_vcc()
109 for (walk = &entry->vccs; *walk; walk = &(*walk)->next) in unlink_clip_vcc()
113 *walk = clip_vcc->next; /* atomic */ in unlink_clip_vcc()
114 clip_vcc->entry = NULL; in unlink_clip_vcc()
115 if (clip_vcc->xoff) in unlink_clip_vcc()
116 netif_wake_queue(entry->neigh->dev); in unlink_clip_vcc()
117 if (entry->vccs) in unlink_clip_vcc()
119 entry->expires = jiffies - 1; in unlink_clip_vcc()
121 error = neigh_update(entry->neigh, NULL, NUD_NONE, in unlink_clip_vcc()
127 pr_err("ATMARP: failed (entry %p, vcc 0x%p)\n", entry, clip_vcc); in unlink_clip_vcc()
129 netif_tx_unlock_bh(entry->neigh->dev); in unlink_clip_vcc()
132 /* The neighbour entry n->lock is held. */
138 if (n->ops != &clip_neigh_ops) in neigh_check_cb()
140 for (cv = entry->vccs; cv; cv = cv->next) { in neigh_check_cb()
141 unsigned long exp = cv->last_use + cv->idle_timeout; in neigh_check_cb()
143 if (cv->idle_timeout && time_after(jiffies, exp)) { in neigh_check_cb()
144 pr_debug("releasing vcc %p->%p of entry %p\n", in neigh_check_cb()
145 cv, cv->vcc, entry); in neigh_check_cb()
146 vcc_release_async(cv->vcc, -ETIMEDOUT); in neigh_check_cb()
150 if (entry->vccs || time_before(jiffies, entry->expires)) in neigh_check_cb()
153 if (refcount_read(&n->refcnt) > 1) { in neigh_check_cb()
157 refcount_read(&n->refcnt)); in neigh_check_cb()
159 while ((skb = skb_dequeue(&n->arp_queue)) != NULL) in neigh_check_cb()
165 pr_debug("expired neigh %p\n", n); in neigh_check_cb()
179 struct atm_vcc *vcc; in clip_arp_rcv() local
182 vcc = ATM_SKB(skb)->vcc; in clip_arp_rcv()
183 if (!vcc || !atm_charge(vcc, skb->truesize)) { in clip_arp_rcv()
187 pr_debug("pushing to %p\n", vcc); in clip_arp_rcv()
188 pr_debug("using %p\n", CLIP_VCC(vcc)->old_push); in clip_arp_rcv()
189 CLIP_VCC(vcc)->old_push(vcc, skb); in clip_arp_rcv()
194 0xaa, /* DSAP: non-ISO */
195 0xaa, /* SSAP: non-ISO */
202 static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) in clip_push() argument
204 struct clip_vcc *clip_vcc = CLIP_VCC(vcc); in clip_push()
209 pr_debug("removing VCC %p\n", clip_vcc); in clip_push()
210 if (clip_vcc->entry) in clip_push()
212 clip_vcc->old_push(vcc, NULL); /* pass on the bad news */ in clip_push()
216 atm_return(vcc, skb->truesize); in clip_push()
222 skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs; in clip_push()
223 /* clip_vcc->entry == NULL if we don't have an IP address yet */ in clip_push()
224 if (!skb->dev) { in clip_push()
228 ATM_SKB(skb)->vcc = vcc; in clip_push()
230 if (!clip_vcc->encap || in clip_push()
231 skb->len < RFC1483LLC_LEN || in clip_push()
232 memcmp(skb->data, llc_oui, sizeof(llc_oui))) in clip_push()
233 skb->protocol = htons(ETH_P_IP); in clip_push()
235 skb->protocol = ((__be16 *)skb->data)[3]; in clip_push()
237 if (skb->protocol == htons(ETH_P_ARP)) { in clip_push()
238 skb->dev->stats.rx_packets++; in clip_push()
239 skb->dev->stats.rx_bytes += skb->len; in clip_push()
244 clip_vcc->last_use = jiffies; in clip_push()
245 skb->dev->stats.rx_packets++; in clip_push()
246 skb->dev->stats.rx_bytes += skb->len; in clip_push()
252 * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
256 static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb) in clip_pop() argument
258 struct clip_vcc *clip_vcc = CLIP_VCC(vcc); in clip_pop()
259 struct net_device *dev = skb->dev; in clip_pop()
263 pr_debug("(vcc %p)\n", vcc); in clip_pop()
264 clip_vcc->old_pop(vcc, skb); in clip_pop()
265 /* skb->dev == NULL in outbound ARP packets */ in clip_pop()
268 spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags); in clip_pop()
269 if (atm_may_send(vcc, 0)) { in clip_pop()
270 old = xchg(&clip_vcc->xoff, 0); in clip_pop()
274 spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); in clip_pop()
279 __be32 *ip = (__be32 *) neigh->primary_key; in clip_neigh_solicit()
281 pr_debug("(neigh %p, skb %p)\n", neigh, skb); in clip_neigh_solicit()
282 to_atmarpd(act_need, PRIV(neigh->dev)->number, *ip); in clip_neigh_solicit()
305 if (neigh->tbl->family != AF_INET) in clip_constructor()
306 return -EINVAL; in clip_constructor()
308 if (neigh->type != RTN_UNICAST) in clip_constructor()
309 return -EINVAL; in clip_constructor()
311 neigh->nud_state = NUD_NONE; in clip_constructor()
312 neigh->ops = &clip_neigh_ops; in clip_constructor()
313 neigh->output = neigh->ops->output; in clip_constructor()
314 entry->neigh = neigh; in clip_constructor()
315 entry->vccs = NULL; in clip_constructor()
316 entry->expires = jiffies - 1; in clip_constructor()
321 /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
324 * We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
330 static int clip_encap(struct atm_vcc *vcc, int mode) in clip_encap() argument
332 if (!CLIP_VCC(vcc)) in clip_encap()
333 return -EBADFD; in clip_encap()
335 CLIP_VCC(vcc)->encap = mode; in clip_encap()
346 struct atm_vcc *vcc; in clip_start_xmit() local
352 pr_debug("(skb %p)\n", skb); in clip_start_xmit()
356 dev->stats.tx_dropped++; in clip_start_xmit()
360 if (rt->rt_gw_family == AF_INET) in clip_start_xmit()
361 daddr = &rt->rt_gw4; in clip_start_xmit()
363 daddr = &ip_hdr(skb)->daddr; in clip_start_xmit()
368 dev->stats.tx_dropped++; in clip_start_xmit()
372 if (!entry->vccs) { in clip_start_xmit()
373 if (time_after(jiffies, entry->expires)) { in clip_start_xmit()
375 entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ; in clip_start_xmit()
376 to_atmarpd(act_need, PRIV(dev)->number, *((__be32 *)n->primary_key)); in clip_start_xmit()
378 if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS) in clip_start_xmit()
379 skb_queue_tail(&entry->neigh->arp_queue, skb); in clip_start_xmit()
382 dev->stats.tx_dropped++; in clip_start_xmit()
386 pr_debug("neigh %p, vccs %p\n", entry, entry->vccs); in clip_start_xmit()
387 ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc; in clip_start_xmit()
388 pr_debug("using neighbour %p, vcc %p\n", n, vcc); in clip_start_xmit()
389 if (entry->vccs->encap) { in clip_start_xmit()
394 ((__be16 *) here)[3] = skb->protocol; in clip_start_xmit()
396 atm_account_tx(vcc, skb); in clip_start_xmit()
397 entry->vccs->last_use = jiffies; in clip_start_xmit()
398 pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev); in clip_start_xmit()
399 old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */ in clip_start_xmit()
401 pr_warn("XOFF->XOFF transition\n"); in clip_start_xmit()
404 dev->stats.tx_packets++; in clip_start_xmit()
405 dev->stats.tx_bytes += skb->len; in clip_start_xmit()
406 vcc->send(vcc, skb); in clip_start_xmit()
407 if (atm_may_send(vcc, 0)) { in clip_start_xmit()
408 entry->vccs->xoff = 0; in clip_start_xmit()
411 spin_lock_irqsave(&clip_priv->xoff_lock, flags); in clip_start_xmit()
412 netif_stop_queue(dev); /* XOFF -> throttle immediately */ in clip_start_xmit()
414 if (!entry->vccs->xoff) in clip_start_xmit()
420 spin_unlock_irqrestore(&clip_priv->xoff_lock, flags); in clip_start_xmit()
426 static int clip_mkip(struct atm_vcc *vcc, int timeout) in clip_mkip() argument
430 if (!vcc->push) in clip_mkip()
431 return -EBADFD; in clip_mkip()
432 if (vcc->user_back) in clip_mkip()
433 return -EINVAL; in clip_mkip()
436 return -ENOMEM; in clip_mkip()
437 pr_debug("%p vcc %p\n", clip_vcc, vcc); in clip_mkip()
438 clip_vcc->vcc = vcc; in clip_mkip()
439 vcc->user_back = clip_vcc; in clip_mkip()
440 set_bit(ATM_VF_IS_CLIP, &vcc->flags); in clip_mkip()
441 clip_vcc->entry = NULL; in clip_mkip()
442 clip_vcc->xoff = 0; in clip_mkip()
443 clip_vcc->encap = 1; in clip_mkip()
444 clip_vcc->last_use = jiffies; in clip_mkip()
445 clip_vcc->idle_timeout = timeout * HZ; in clip_mkip()
446 clip_vcc->old_push = vcc->push; in clip_mkip()
447 clip_vcc->old_pop = vcc->pop; in clip_mkip()
448 vcc->push = clip_push; in clip_mkip()
449 vcc->pop = clip_pop; in clip_mkip()
451 /* re-process everything received between connection setup and MKIP */ in clip_mkip()
452 vcc_process_recv_queue(vcc); in clip_mkip()
457 static int clip_setentry(struct atm_vcc *vcc, __be32 ip) in clip_setentry() argument
465 if (vcc->push != clip_push) { in clip_setentry()
466 pr_warn("non-CLIP VCC\n"); in clip_setentry()
467 return -EBADF; in clip_setentry()
469 clip_vcc = CLIP_VCC(vcc); in clip_setentry()
471 if (!clip_vcc->entry) { in clip_setentry()
482 neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1); in clip_setentry()
485 return -ENOMEM; in clip_setentry()
487 if (entry != clip_vcc->entry) { in clip_setentry()
488 if (!clip_vcc->entry) in clip_setentry()
509 dev->netdev_ops = &clip_netdev_ops; in clip_setup()
510 dev->type = ARPHRD_ATM; in clip_setup()
511 dev->neigh_priv_len = sizeof(struct atmarp_entry); in clip_setup()
512 dev->hard_header_len = RFC1483LLC_LEN; in clip_setup()
513 dev->mtu = RFC1626_MTU; in clip_setup()
514 dev->tx_queue_len = 100; /* "normal" queue (packets) */ in clip_setup()
518 /* compromise between decent burst-tolerance and protection */ in clip_setup()
529 if (number != -1) { in clip_create()
530 for (dev = clip_devs; dev; dev = PRIV(dev)->next) in clip_create()
531 if (PRIV(dev)->number == number) in clip_create()
532 return -EEXIST; in clip_create()
535 for (dev = clip_devs; dev; dev = PRIV(dev)->next) in clip_create()
536 if (PRIV(dev)->number >= number) in clip_create()
537 number = PRIV(dev)->number + 1; in clip_create()
542 return -ENOMEM; in clip_create()
544 sprintf(dev->name, "atm%d", number); in clip_create()
545 spin_lock_init(&clip_priv->xoff_lock); in clip_create()
546 clip_priv->number = number; in clip_create()
552 clip_priv->next = clip_devs; in clip_create()
554 pr_debug("registered (net:%s)\n", dev->name); in clip_create()
569 /* ignore non-CLIP devices */ in clip_device_event()
570 if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops) in clip_device_event()
576 to_atmarpd(act_up, PRIV(dev)->number, 0); in clip_device_event()
580 to_atmarpd(act_down, PRIV(dev)->number, 0); in clip_device_event()
585 to_atmarpd(act_change, PRIV(dev)->number, 0); in clip_device_event()
597 in_dev = ((struct in_ifaddr *)ifa)->ifa_dev; in clip_inet_event()
599 * Transitions are of the down-change-up type, so it's sufficient to in clip_inet_event()
604 netdev_notifier_info_init(&info, in_dev->dev); in clip_inet_event()
620 static void atmarpd_close(struct atm_vcc *vcc) in atmarpd_close() argument
629 skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); in atmarpd_close()
635 static int atmarpd_send(struct atm_vcc *vcc, struct sk_buff *skb) in atmarpd_send() argument
637 atm_return_tx(vcc, skb); in atmarpd_send()
656 static int atm_init_atmarp(struct atm_vcc *vcc) in atm_init_atmarp() argument
658 if (vcc->push == clip_push) in atm_init_atmarp()
659 return -EINVAL; in atm_init_atmarp()
664 return -EADDRINUSE; in atm_init_atmarp()
669 rcu_assign_pointer(atmarpd, vcc); in atm_init_atmarp()
670 set_bit(ATM_VF_META, &vcc->flags); in atm_init_atmarp()
671 set_bit(ATM_VF_READY, &vcc->flags); in atm_init_atmarp()
673 vcc->dev = &atmarpd_dev; in atm_init_atmarp()
674 vcc_insert_socket(sk_atm(vcc)); in atm_init_atmarp()
675 vcc->push = NULL; in atm_init_atmarp()
676 vcc->pop = NULL; /* crash */ in atm_init_atmarp()
677 vcc->push_oam = NULL; /* crash */ in atm_init_atmarp()
684 struct atm_vcc *vcc = ATM_SD(sock); in clip_ioctl() local
685 struct sock *sk = sock->sk; in clip_ioctl()
695 return -EPERM; in clip_ioctl()
698 return -ENOIOCTLCMD; in clip_ioctl()
707 err = atm_init_atmarp(vcc); in clip_ioctl()
709 sock->state = SS_CONNECTED; in clip_ioctl()
716 err = clip_mkip(vcc, arg); in clip_ioctl()
720 err = clip_setentry(vcc, (__force __be32)arg); in clip_ioctl()
723 err = clip_encap(vcc, arg); in clip_ioctl()
741 if (*addr->sas_addr.pub) { in svc_addr()
742 seq_printf(seq, "%s", addr->sas_addr.pub); in svc_addr()
743 if (*addr->sas_addr.prv) in svc_addr()
745 } else if (!*addr->sas_addr.prv) { in svc_addr()
749 if (*addr->sas_addr.prv) { in svc_addr()
750 unsigned char *prv = addr->sas_addr.prv; in svc_addr()
756 for (j = fields[i]; j; j--) in svc_addr()
764 /* This means the neighbour entry has no attached VCC objects. */
770 struct net_device *dev = n->dev; in atmarp_info()
776 (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC)); in atmarp_info()
778 llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap); in atmarp_info()
781 exp = entry->neigh->used; in atmarp_info()
783 exp = clip_vcc->last_use; in atmarp_info()
785 exp = (jiffies - exp) / HZ; in atmarp_info()
787 seq_printf(seq, "%-6s%-4s%-4s%5ld ", in atmarp_info()
788 dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp); in atmarp_info()
790 off = scnprintf(buf, sizeof(buf) - 1, "%pI4", n->primary_key); in atmarp_info()
797 if (time_before(jiffies, entry->expires)) in atmarp_info()
801 refcount_read(&entry->neigh->refcnt)); in atmarp_info()
804 clip_vcc->vcc->dev->number, in atmarp_info()
805 clip_vcc->vcc->vpi, clip_vcc->vcc->vci); in atmarp_info()
807 svc_addr(seq, &clip_vcc->vcc->remote); in atmarp_info()
817 struct clip_vcc *vcc; member
824 curr = e->vccs; in clip_seq_next_vcc()
832 curr = curr->next; in clip_seq_next_vcc()
840 struct clip_vcc *vcc = state->vcc; in clip_seq_vcc_walk() local
842 vcc = clip_seq_next_vcc(e, vcc); in clip_seq_vcc_walk()
843 if (vcc && pos != NULL) { in clip_seq_vcc_walk()
845 vcc = clip_seq_next_vcc(e, vcc); in clip_seq_vcc_walk()
846 if (!vcc) in clip_seq_vcc_walk()
848 --(*pos); in clip_seq_vcc_walk()
851 state->vcc = vcc; in clip_seq_vcc_walk()
853 return vcc; in clip_seq_vcc_walk()
861 if (n->dev->type != ARPHRD_ATM) in clip_seq_sub_iter()
869 struct clip_seq_state *state = seq->private; in clip_seq_start()
870 state->ns.neigh_sub_iter = clip_seq_sub_iter; in clip_seq_start()
882 struct clip_seq_state *state = seq->private; in clip_seq_show()
883 struct clip_vcc *vcc = state->vcc; in clip_seq_show() local
886 atmarp_info(seq, n, neighbour_priv(n), vcc); in clip_seq_show()
911 struct proc_dir_entry *p; in atm_clip_init() local
913 p = proc_create_net("arp", 0444, atm_proc_root, &arp_seq_ops, in atm_clip_init()
915 if (!p) { in atm_clip_init()
918 return -ENOMEM; in atm_clip_init()
942 next = PRIV(dev)->next; in atm_clip_exit_noproc()