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 */
60 return -EUNATCH; in to_atmarpd()
63 return -ENOMEM; in to_atmarpd()
65 ctrl->type = type; in to_atmarpd()
66 ctrl->itf_num = itf; in to_atmarpd()
67 ctrl->ip = ip; in to_atmarpd()
68 atm_force_charge(atmarpd, skb->truesize); in to_atmarpd()
71 skb_queue_tail(&sk->sk_receive_queue, skb); in to_atmarpd()
72 sk->sk_data_ready(sk); in to_atmarpd()
78 pr_debug("%p to entry %p (neigh %p)\n", clip_vcc, entry, entry->neigh); in link_vcc()
79 clip_vcc->entry = entry; in link_vcc()
80 clip_vcc->xoff = 0; /* @@@ may overrun buffer by one packet */ in link_vcc()
81 clip_vcc->next = entry->vccs; in link_vcc()
82 entry->vccs = clip_vcc; in link_vcc()
83 entry->neigh->used = jiffies; in link_vcc()
88 struct atmarp_entry *entry = clip_vcc->entry; in unlink_clip_vcc()
92 pr_err("!clip_vcc->entry (clip_vcc %p)\n", clip_vcc); in unlink_clip_vcc()
95 netif_tx_lock_bh(entry->neigh->dev); /* block clip_start_xmit() */ in unlink_clip_vcc()
96 entry->neigh->used = jiffies; in unlink_clip_vcc()
97 for (walk = &entry->vccs; *walk; walk = &(*walk)->next) in unlink_clip_vcc()
101 *walk = clip_vcc->next; /* atomic */ in unlink_clip_vcc()
102 clip_vcc->entry = NULL; in unlink_clip_vcc()
103 if (clip_vcc->xoff) in unlink_clip_vcc()
104 netif_wake_queue(entry->neigh->dev); in unlink_clip_vcc()
105 if (entry->vccs) in unlink_clip_vcc()
107 entry->expires = jiffies - 1; in unlink_clip_vcc()
109 error = neigh_update(entry->neigh, NULL, NUD_NONE, in unlink_clip_vcc()
115 pr_err("ATMARP: failed (entry %p, vcc 0x%p)\n", entry, clip_vcc); in unlink_clip_vcc()
117 netif_tx_unlock_bh(entry->neigh->dev); in unlink_clip_vcc()
120 /* The neighbour entry n->lock is held. */
126 if (n->ops != &clip_neigh_ops) in neigh_check_cb()
128 for (cv = entry->vccs; cv; cv = cv->next) { in neigh_check_cb()
129 unsigned long exp = cv->last_use + cv->idle_timeout; in neigh_check_cb()
131 if (cv->idle_timeout && time_after(jiffies, exp)) { in neigh_check_cb()
132 pr_debug("releasing vcc %p->%p of entry %p\n", in neigh_check_cb()
133 cv, cv->vcc, entry); in neigh_check_cb()
134 vcc_release_async(cv->vcc, -ETIMEDOUT); in neigh_check_cb()
138 if (entry->vccs || time_before(jiffies, entry->expires)) in neigh_check_cb()
141 if (refcount_read(&n->refcnt) > 1) { in neigh_check_cb()
145 refcount_read(&n->refcnt)); in neigh_check_cb()
147 while ((skb = skb_dequeue(&n->arp_queue)) != NULL) in neigh_check_cb()
153 pr_debug("expired neigh %p\n", n); in neigh_check_cb()
167 struct atm_vcc *vcc; in clip_arp_rcv() local
170 vcc = ATM_SKB(skb)->vcc; in clip_arp_rcv()
171 if (!vcc || !atm_charge(vcc, skb->truesize)) { in clip_arp_rcv()
175 pr_debug("pushing to %p\n", vcc); in clip_arp_rcv()
176 pr_debug("using %p\n", CLIP_VCC(vcc)->old_push); in clip_arp_rcv()
177 CLIP_VCC(vcc)->old_push(vcc, skb); in clip_arp_rcv()
182 0xaa, /* DSAP: non-ISO */
183 0xaa, /* SSAP: non-ISO */
190 static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) in clip_push() argument
192 struct clip_vcc *clip_vcc = CLIP_VCC(vcc); in clip_push()
197 atm_return(vcc, skb->truesize); in clip_push()
203 pr_debug("removing VCC %p\n", clip_vcc); in clip_push()
204 if (clip_vcc->entry) in clip_push()
206 clip_vcc->old_push(vcc, NULL); /* pass on the bad news */ in clip_push()
210 atm_return(vcc, skb->truesize); in clip_push()
211 skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs; in clip_push()
212 /* clip_vcc->entry == NULL if we don't have an IP address yet */ in clip_push()
213 if (!skb->dev) { in clip_push()
217 ATM_SKB(skb)->vcc = vcc; in clip_push()
219 if (!clip_vcc->encap || in clip_push()
220 skb->len < RFC1483LLC_LEN || in clip_push()
221 memcmp(skb->data, llc_oui, sizeof(llc_oui))) in clip_push()
222 skb->protocol = htons(ETH_P_IP); in clip_push()
224 skb->protocol = ((__be16 *)skb->data)[3]; in clip_push()
226 if (skb->protocol == htons(ETH_P_ARP)) { in clip_push()
227 skb->dev->stats.rx_packets++; in clip_push()
228 skb->dev->stats.rx_bytes += skb->len; in clip_push()
233 clip_vcc->last_use = jiffies; in clip_push()
234 skb->dev->stats.rx_packets++; in clip_push()
235 skb->dev->stats.rx_bytes += skb->len; in clip_push()
241 * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
245 static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb) in clip_pop() argument
247 struct clip_vcc *clip_vcc = CLIP_VCC(vcc); in clip_pop()
248 struct net_device *dev = skb->dev; in clip_pop()
252 pr_debug("(vcc %p)\n", vcc); in clip_pop()
253 clip_vcc->old_pop(vcc, skb); in clip_pop()
254 /* skb->dev == NULL in outbound ARP packets */ in clip_pop()
257 spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags); in clip_pop()
258 if (atm_may_send(vcc, 0)) { in clip_pop()
259 old = xchg(&clip_vcc->xoff, 0); in clip_pop()
263 spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); in clip_pop()
268 __be32 *ip = (__be32 *) neigh->primary_key; in clip_neigh_solicit()
270 pr_debug("(neigh %p, skb %p)\n", neigh, skb); in clip_neigh_solicit()
271 to_atmarpd(act_need, PRIV(neigh->dev)->number, *ip); in clip_neigh_solicit()
294 if (neigh->tbl->family != AF_INET) in clip_constructor()
295 return -EINVAL; in clip_constructor()
297 if (neigh->type != RTN_UNICAST) in clip_constructor()
298 return -EINVAL; in clip_constructor()
300 neigh->nud_state = NUD_NONE; in clip_constructor()
301 neigh->ops = &clip_neigh_ops; in clip_constructor()
302 neigh->output = neigh->ops->output; in clip_constructor()
303 entry->neigh = neigh; in clip_constructor()
304 entry->vccs = NULL; in clip_constructor()
305 entry->expires = jiffies - 1; in clip_constructor()
310 /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
313 * We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
319 static int clip_encap(struct atm_vcc *vcc, int mode) in clip_encap() argument
321 if (!CLIP_VCC(vcc)) in clip_encap()
322 return -EBADFD; in clip_encap()
324 CLIP_VCC(vcc)->encap = mode; in clip_encap()
335 struct atm_vcc *vcc; in clip_start_xmit() local
341 pr_debug("(skb %p)\n", skb); in clip_start_xmit()
345 dev->stats.tx_dropped++; in clip_start_xmit()
349 if (rt->rt_gw_family == AF_INET) in clip_start_xmit()
350 daddr = &rt->rt_gw4; in clip_start_xmit()
352 daddr = &ip_hdr(skb)->daddr; in clip_start_xmit()
357 dev->stats.tx_dropped++; in clip_start_xmit()
361 if (!entry->vccs) { in clip_start_xmit()
362 if (time_after(jiffies, entry->expires)) { in clip_start_xmit()
364 entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ; in clip_start_xmit()
365 to_atmarpd(act_need, PRIV(dev)->number, *((__be32 *)n->primary_key)); in clip_start_xmit()
367 if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS) in clip_start_xmit()
368 skb_queue_tail(&entry->neigh->arp_queue, skb); in clip_start_xmit()
371 dev->stats.tx_dropped++; in clip_start_xmit()
375 pr_debug("neigh %p, vccs %p\n", entry, entry->vccs); in clip_start_xmit()
376 ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc; in clip_start_xmit()
377 pr_debug("using neighbour %p, vcc %p\n", n, vcc); in clip_start_xmit()
378 if (entry->vccs->encap) { in clip_start_xmit()
383 ((__be16 *) here)[3] = skb->protocol; in clip_start_xmit()
385 atm_account_tx(vcc, skb); in clip_start_xmit()
386 entry->vccs->last_use = jiffies; in clip_start_xmit()
387 pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev); in clip_start_xmit()
388 old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */ in clip_start_xmit()
390 pr_warn("XOFF->XOFF transition\n"); in clip_start_xmit()
393 dev->stats.tx_packets++; in clip_start_xmit()
394 dev->stats.tx_bytes += skb->len; in clip_start_xmit()
395 vcc->send(vcc, skb); in clip_start_xmit()
396 if (atm_may_send(vcc, 0)) { in clip_start_xmit()
397 entry->vccs->xoff = 0; in clip_start_xmit()
400 spin_lock_irqsave(&clip_priv->xoff_lock, flags); in clip_start_xmit()
401 netif_stop_queue(dev); /* XOFF -> throttle immediately */ in clip_start_xmit()
403 if (!entry->vccs->xoff) in clip_start_xmit()
409 spin_unlock_irqrestore(&clip_priv->xoff_lock, flags); in clip_start_xmit()
415 static int clip_mkip(struct atm_vcc *vcc, int timeout) in clip_mkip() argument
419 if (!vcc->push) in clip_mkip()
420 return -EBADFD; in clip_mkip()
423 return -ENOMEM; in clip_mkip()
424 pr_debug("%p vcc %p\n", clip_vcc, vcc); in clip_mkip()
425 clip_vcc->vcc = vcc; in clip_mkip()
426 vcc->user_back = clip_vcc; in clip_mkip()
427 set_bit(ATM_VF_IS_CLIP, &vcc->flags); in clip_mkip()
428 clip_vcc->entry = NULL; in clip_mkip()
429 clip_vcc->xoff = 0; in clip_mkip()
430 clip_vcc->encap = 1; in clip_mkip()
431 clip_vcc->last_use = jiffies; in clip_mkip()
432 clip_vcc->idle_timeout = timeout * HZ; in clip_mkip()
433 clip_vcc->old_push = vcc->push; in clip_mkip()
434 clip_vcc->old_pop = vcc->pop; in clip_mkip()
435 vcc->push = clip_push; in clip_mkip()
436 vcc->pop = clip_pop; in clip_mkip()
438 /* re-process everything received between connection setup and MKIP */ in clip_mkip()
439 vcc_process_recv_queue(vcc); in clip_mkip()
444 static int clip_setentry(struct atm_vcc *vcc, __be32 ip) in clip_setentry() argument
452 if (vcc->push != clip_push) { in clip_setentry()
453 pr_warn("non-CLIP VCC\n"); in clip_setentry()
454 return -EBADF; in clip_setentry()
456 clip_vcc = CLIP_VCC(vcc); in clip_setentry()
458 if (!clip_vcc->entry) { in clip_setentry()
469 neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1); in clip_setentry()
472 return -ENOMEM; in clip_setentry()
474 if (entry != clip_vcc->entry) { in clip_setentry()
475 if (!clip_vcc->entry) in clip_setentry()
496 dev->netdev_ops = &clip_netdev_ops; in clip_setup()
497 dev->type = ARPHRD_ATM; in clip_setup()
498 dev->neigh_priv_len = sizeof(struct atmarp_entry); in clip_setup()
499 dev->hard_header_len = RFC1483LLC_LEN; in clip_setup()
500 dev->mtu = RFC1626_MTU; in clip_setup()
501 dev->tx_queue_len = 100; /* "normal" queue (packets) */ in clip_setup()
505 /* compromise between decent burst-tolerance and protection */ in clip_setup()
516 if (number != -1) { in clip_create()
517 for (dev = clip_devs; dev; dev = PRIV(dev)->next) in clip_create()
518 if (PRIV(dev)->number == number) in clip_create()
519 return -EEXIST; in clip_create()
522 for (dev = clip_devs; dev; dev = PRIV(dev)->next) in clip_create()
523 if (PRIV(dev)->number >= number) in clip_create()
524 number = PRIV(dev)->number + 1; in clip_create()
529 return -ENOMEM; in clip_create()
531 sprintf(dev->name, "atm%d", number); in clip_create()
532 spin_lock_init(&clip_priv->xoff_lock); in clip_create()
533 clip_priv->number = number; in clip_create()
539 clip_priv->next = clip_devs; in clip_create()
541 pr_debug("registered (net:%s)\n", dev->name); in clip_create()
556 /* ignore non-CLIP devices */ in clip_device_event()
557 if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops) in clip_device_event()
563 to_atmarpd(act_up, PRIV(dev)->number, 0); in clip_device_event()
567 to_atmarpd(act_down, PRIV(dev)->number, 0); in clip_device_event()
572 to_atmarpd(act_change, PRIV(dev)->number, 0); in clip_device_event()
584 in_dev = ((struct in_ifaddr *)ifa)->ifa_dev; in clip_inet_event()
586 * Transitions are of the down-change-up type, so it's sufficient to in clip_inet_event()
591 netdev_notifier_info_init(&info, in_dev->dev); in clip_inet_event()
607 static void atmarpd_close(struct atm_vcc *vcc) in atmarpd_close() argument
613 skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); in atmarpd_close()
633 static int atm_init_atmarp(struct atm_vcc *vcc) in atm_init_atmarp() argument
638 return -EADDRINUSE; in atm_init_atmarp()
643 atmarpd = vcc; in atm_init_atmarp()
644 set_bit(ATM_VF_META, &vcc->flags); in atm_init_atmarp()
645 set_bit(ATM_VF_READY, &vcc->flags); in atm_init_atmarp()
647 vcc->dev = &atmarpd_dev; in atm_init_atmarp()
648 vcc_insert_socket(sk_atm(vcc)); in atm_init_atmarp()
649 vcc->push = NULL; in atm_init_atmarp()
650 vcc->pop = NULL; /* crash */ in atm_init_atmarp()
651 vcc->push_oam = NULL; /* crash */ in atm_init_atmarp()
658 struct atm_vcc *vcc = ATM_SD(sock); in clip_ioctl() local
668 return -EPERM; in clip_ioctl()
671 return -ENOIOCTLCMD; in clip_ioctl()
679 err = atm_init_atmarp(vcc); in clip_ioctl()
681 sock->state = SS_CONNECTED; in clip_ioctl()
686 err = clip_mkip(vcc, arg); in clip_ioctl()
689 err = clip_setentry(vcc, (__force __be32)arg); in clip_ioctl()
692 err = clip_encap(vcc, arg); in clip_ioctl()
710 if (*addr->sas_addr.pub) { in svc_addr()
711 seq_printf(seq, "%s", addr->sas_addr.pub); in svc_addr()
712 if (*addr->sas_addr.prv) in svc_addr()
714 } else if (!*addr->sas_addr.prv) { in svc_addr()
718 if (*addr->sas_addr.prv) { in svc_addr()
719 unsigned char *prv = addr->sas_addr.prv; in svc_addr()
725 for (j = fields[i]; j; j--) in svc_addr()
733 /* This means the neighbour entry has no attached VCC objects. */
739 struct net_device *dev = n->dev; in atmarp_info()
745 (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC)); in atmarp_info()
747 llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap); in atmarp_info()
750 exp = entry->neigh->used; in atmarp_info()
752 exp = clip_vcc->last_use; in atmarp_info()
754 exp = (jiffies - exp) / HZ; in atmarp_info()
756 seq_printf(seq, "%-6s%-4s%-4s%5ld ", in atmarp_info()
757 dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp); in atmarp_info()
759 off = scnprintf(buf, sizeof(buf) - 1, "%pI4", n->primary_key); in atmarp_info()
766 if (time_before(jiffies, entry->expires)) in atmarp_info()
770 refcount_read(&entry->neigh->refcnt)); in atmarp_info()
773 clip_vcc->vcc->dev->number, in atmarp_info()
774 clip_vcc->vcc->vpi, clip_vcc->vcc->vci); in atmarp_info()
776 svc_addr(seq, &clip_vcc->vcc->remote); in atmarp_info()
786 struct clip_vcc *vcc; member
793 curr = e->vccs; in clip_seq_next_vcc()
801 curr = curr->next; in clip_seq_next_vcc()
809 struct clip_vcc *vcc = state->vcc; in clip_seq_vcc_walk() local
811 vcc = clip_seq_next_vcc(e, vcc); in clip_seq_vcc_walk()
812 if (vcc && pos != NULL) { in clip_seq_vcc_walk()
814 vcc = clip_seq_next_vcc(e, vcc); in clip_seq_vcc_walk()
815 if (!vcc) in clip_seq_vcc_walk()
817 --(*pos); in clip_seq_vcc_walk()
820 state->vcc = vcc; in clip_seq_vcc_walk()
822 return vcc; in clip_seq_vcc_walk()
830 if (n->dev->type != ARPHRD_ATM) in clip_seq_sub_iter()
838 struct clip_seq_state *state = seq->private; in clip_seq_start()
839 state->ns.neigh_sub_iter = clip_seq_sub_iter; in clip_seq_start()
851 struct clip_seq_state *state = seq->private; in clip_seq_show()
852 struct clip_vcc *vcc = state->vcc; in clip_seq_show() local
855 atmarp_info(seq, n, neighbour_priv(n), vcc); in clip_seq_show()
880 struct proc_dir_entry *p; in atm_clip_init() local
882 p = proc_create_net("arp", 0444, atm_proc_root, &arp_seq_ops, in atm_clip_init()
884 if (!p) { in atm_clip_init()
887 return -ENOMEM; in atm_clip_init()
911 next = PRIV(dev)->next; in atm_clip_exit_noproc()