Lines Matching +full:protocol +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0-only
4 * Point-to-point protocol support
6 * Copyright (C) 1999 - 2008 Krzysztof Halasa <khc@pm.waw.pl>
52 __be16 protocol; member
57 u8 id; member
66 u16 pid; /* protocol ID */
68 u8 cr_id; /* ID of last Configuration-Request */
79 u8 echo_id; /* ID of last Echo-Request (LCP) */
95 "Start", "Stop", "TO+", "TO-", "RCR+", "RCR-", "RCA", "RCN",
96 "RTR", "RTA", "RUC", "RXJ+", "RXJ-"
106 return (struct ppp *)dev_to_hdlc(dev)->state; in get_ppp()
115 return &ppp->protos[IDX_LCP]; in get_proto()
117 return &ppp->protos[IDX_IPCP]; in get_proto()
119 return &ppp->protos[IDX_IPV6CP]; in get_proto()
141 struct hdlc_header *data = (struct hdlc_header*)skb->data; in ppp_type_trans()
143 if (skb->len < sizeof(struct hdlc_header)) in ppp_type_trans()
145 if (data->address != HDLC_ADDR_ALLSTATIONS || in ppp_type_trans()
146 data->control != HDLC_CTRL_UI) in ppp_type_trans()
149 switch (data->protocol) { in ppp_type_trans()
170 printk(KERN_DEBUG "%s: ppp_hard_header() called\n", dev->name); in ppp_hard_header()
174 data = (struct hdlc_header*)skb->data; in ppp_hard_header()
176 data->address = HDLC_ADDR_ALLSTATIONS; in ppp_hard_header()
177 data->control = HDLC_CTRL_UI; in ppp_hard_header()
180 data->protocol = htons(PID_IP); in ppp_hard_header()
183 data->protocol = htons(PID_IPV6); in ppp_hard_header()
188 data->protocol = htons(type); in ppp_hard_header()
190 default: /* unknown protocol */ in ppp_hard_header()
191 data->protocol = 0; in ppp_hard_header()
205 u8 id, unsigned int len, const void *data) in ppp_tx_cp() argument
229 cp->code = code; in ppp_tx_cp()
230 cp->id = id; in ppp_tx_cp()
231 cp->len = htons(sizeof(struct cp_header) + magic_len + len); in ppp_tx_cp()
243 sprintf(ptr, " %02X", skb->data[sizeof(struct cp_header) + i]); in ppp_tx_cp()
246 printk(KERN_DEBUG "%s: TX %s [%s id 0x%X]%s\n", dev->name, in ppp_tx_cp()
247 proto_name(pid), code_names[code], id, debug_buffer); in ppp_tx_cp()
252 skb->priority = TC_PRIO_CONTROL; in ppp_tx_cp()
253 skb->dev = dev; in ppp_tx_cp()
254 skb->protocol = htons(ETH_P_HDLC); in ppp_tx_cp()
260 /* State transition table (compare STD-51)
262 TO+ = Timeout with counter > 0 irc = Initialize-Restart-Count
263 TO- = Timeout with counter expired zrc = Zero-Restart-Count
265 RCR+ = Receive-Configure-Request (Good) scr = Send-Configure-Request
266 RCR- = Receive-Configure-Request (Bad)
267 RCA = Receive-Configure-Ack sca = Send-Configure-Ack
268 RCN = Receive-Configure-Nak/Rej scn = Send-Configure-Nak/Rej
270 RTR = Receive-Terminate-Request str = Send-Terminate-Request
271 RTA = Receive-Terminate-Ack sta = Send-Terminate-Ack
273 RUC = Receive-Unknown-Code scj = Send-Code-Reject
274 RXJ+ = Receive-Code-Reject (permitted)
275 or Receive-Protocol-Reject
276 RXJ- = Receive-Code-Reject (catastrophic)
277 or Receive-Protocol-Reject
285 { INV , INV , 1 , 1 , 1 , 1 , INV }, /* TO- */
287 { STA|0 ,IRC|SCR|SCN|3, 2 , SCN|3 ,SCN|4, SCN|3 ,SCR|SCN|3}, /* RCR- */
294 { 0 , 1 , 1 , 1 , 1 , 1 ,IRC|STR|2}, /* RXJ- */
298 /* SCA: RCR+ must supply id, len and data
299 SCN: RCR- must supply code, id, len and data
300 STA: RTR must supply id
303 u8 id, unsigned int len, const void *data) in ppp_cp_event() argument
309 old_state = proto->state; in ppp_cp_event()
314 printk(KERN_DEBUG "%s: %s ppp_cp_event(%s) %s ...\n", dev->name, in ppp_cp_event()
315 proto_name(pid), event_names[event], state_names[proto->state]); in ppp_cp_event()
320 proto->state = action & STATE_MASK; in ppp_cp_event()
321 if (action & (SCR | STR)) /* set Configure-Req/Terminate-Req timer */ in ppp_cp_event()
322 mod_timer(&proto->timer, proto->timeout = in ppp_cp_event()
323 jiffies + ppp->req_timeout * HZ); in ppp_cp_event()
325 proto->restart_counter = 0; in ppp_cp_event()
327 proto->restart_counter = (proto->state == STOPPING) ? in ppp_cp_event()
328 ppp->term_retries : ppp->cr_retries; in ppp_cp_event()
330 if (action & SCR) /* send Configure-Request */ in ppp_cp_event()
331 ppp_tx_cp(dev, pid, CP_CONF_REQ, proto->cr_id = ++ppp->seq, in ppp_cp_event()
333 if (action & SCA) /* send Configure-Ack */ in ppp_cp_event()
334 ppp_tx_cp(dev, pid, CP_CONF_ACK, id, len, data); in ppp_cp_event()
335 if (action & SCN) /* send Configure-Nak/Reject */ in ppp_cp_event()
336 ppp_tx_cp(dev, pid, code, id, len, data); in ppp_cp_event()
337 if (action & STR) /* send Terminate-Request */ in ppp_cp_event()
338 ppp_tx_cp(dev, pid, CP_TERM_REQ, ++ppp->seq, 0, NULL); in ppp_cp_event()
339 if (action & STA) /* send Terminate-Ack */ in ppp_cp_event()
340 ppp_tx_cp(dev, pid, CP_TERM_ACK, id, 0, NULL); in ppp_cp_event()
341 if (action & SCJ) /* send Code-Reject */ in ppp_cp_event()
342 ppp_tx_cp(dev, pid, CP_CODE_REJ, ++ppp->seq, len, data); in ppp_cp_event()
344 if (old_state != OPENED && proto->state == OPENED) { in ppp_cp_event()
350 ppp->last_pong = jiffies; in ppp_cp_event()
351 mod_timer(&proto->timer, proto->timeout = in ppp_cp_event()
352 jiffies + ppp->keepalive_interval * HZ); in ppp_cp_event()
355 if (old_state == OPENED && proto->state != OPENED) { in ppp_cp_event()
363 if (old_state != CLOSED && proto->state == CLOSED) in ppp_cp_event()
364 del_timer(&proto->timer); in ppp_cp_event()
367 printk(KERN_DEBUG "%s: %s ppp_cp_event(%s) ... %s\n", dev->name, in ppp_cp_event()
368 proto_name(pid), event_names[event], state_names[proto->state]); in ppp_cp_event()
373 static void ppp_cp_parse_cr(struct net_device *dev, u16 pid, u8 id, in ppp_cp_parse_cr() argument
382 dev->stats.rx_dropped++; in ppp_cp_parse_cr()
386 for (opt = data; len; len -= opt[1], opt += opt[1]) { in ppp_cp_parse_cr()
422 ppp_cp_event(dev, pid, RCR_BAD, CP_CONF_REJ, id, rej_len, out); in ppp_cp_parse_cr()
424 ppp_cp_event(dev, pid, RCR_BAD, CP_CONF_NAK, id, nak_len, out); in ppp_cp_parse_cr()
426 ppp_cp_event(dev, pid, RCR_GOOD, CP_CONF_ACK, id, req_len, data); in ppp_cp_parse_cr()
432 dev->stats.rx_errors++; in ppp_cp_parse_cr()
438 struct hdlc_header *hdr = (struct hdlc_header*)skb->data; in ppp_rx()
439 struct net_device *dev = skb->dev; in ppp_rx()
451 spin_lock_irqsave(&ppp->lock, flags); in ppp_rx()
453 if (skb->len < sizeof(struct hdlc_header)) in ppp_rx()
456 if (hdr->address != HDLC_ADDR_ALLSTATIONS || in ppp_rx()
457 hdr->control != HDLC_CTRL_UI) in ppp_rx()
460 pid = ntohs(hdr->protocol); in ppp_rx()
463 if (ppp->protos[IDX_LCP].state == OPENED) in ppp_rx()
465 ++ppp->seq, skb->len + 2, &hdr->protocol); in ppp_rx()
469 len = ntohs(cp->len); in ppp_rx()
471 skb->len < len /* truncated packet? */) in ppp_rx()
474 len -= sizeof(struct cp_header); in ppp_rx()
478 if (cp->code < CP_CODES) in ppp_rx()
479 sprintf(debug_buffer, "[%s id 0x%X]", code_names[cp->code], in ppp_rx()
480 cp->id); in ppp_rx()
482 sprintf(debug_buffer, "[code %u id 0x%X]", cp->code, cp->id); in ppp_rx()
485 sprintf(ptr, " %02X", skb->data[i]); in ppp_rx()
488 printk(KERN_DEBUG "%s: RX %s %s\n", dev->name, proto_name(pid), in ppp_rx()
494 switch (cp->code) { in ppp_rx()
496 pid = ntohs(*(__be16*)skb->data); in ppp_rx()
503 case LCP_ECHO_REQ: /* send Echo-Reply */ in ppp_rx()
504 if (len >= 4 && proto->state == OPENED) in ppp_rx()
506 cp->id, len - 4, skb->data + 4); in ppp_rx()
510 if (cp->id == ppp->echo_id) in ppp_rx()
511 ppp->last_pong = jiffies; in ppp_rx()
519 switch (cp->code) { in ppp_rx()
521 ppp_cp_parse_cr(dev, pid, cp->id, len, skb->data); in ppp_rx()
525 if (cp->id == proto->cr_id) in ppp_rx()
531 if (cp->id == proto->cr_id) in ppp_rx()
536 ppp_cp_event(dev, pid, RTR, 0, cp->id, 0, NULL); in ppp_rx()
549 if (len > dev->mtu) in ppp_rx()
550 len = dev->mtu; in ppp_rx()
557 dev->stats.rx_errors++; in ppp_rx()
559 spin_unlock_irqrestore(&ppp->lock, flags); in ppp_rx()
568 struct ppp *ppp = get_ppp(proto->dev); in ppp_timer()
571 spin_lock_irqsave(&ppp->lock, flags); in ppp_timer()
572 switch (proto->state) { in ppp_timer()
577 if (proto->restart_counter) { in ppp_timer()
578 ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0, in ppp_timer()
580 proto->restart_counter--; in ppp_timer()
581 } else if (netif_carrier_ok(proto->dev)) in ppp_timer()
582 ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0, in ppp_timer()
585 ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0, in ppp_timer()
590 if (proto->pid != PID_LCP) in ppp_timer()
592 if (time_after(jiffies, ppp->last_pong + in ppp_timer()
593 ppp->keepalive_timeout * HZ)) { in ppp_timer()
594 netdev_info(proto->dev, "Link down\n"); in ppp_timer()
595 ppp_cp_event(proto->dev, PID_LCP, STOP, 0, 0, 0, NULL); in ppp_timer()
596 ppp_cp_event(proto->dev, PID_LCP, START, 0, 0, 0, NULL); in ppp_timer()
597 } else { /* send keep-alive packet */ in ppp_timer()
598 ppp->echo_id = ++ppp->seq; in ppp_timer()
599 ppp_tx_cp(proto->dev, PID_LCP, LCP_ECHO_REQ, in ppp_timer()
600 ppp->echo_id, 0, NULL); in ppp_timer()
601 proto->timer.expires = jiffies + in ppp_timer()
602 ppp->keepalive_interval * HZ; in ppp_timer()
603 add_timer(&proto->timer); in ppp_timer()
607 spin_unlock_irqrestore(&ppp->lock, flags); in ppp_timer()
618 struct proto *proto = &ppp->protos[i]; in ppp_start()
619 proto->dev = dev; in ppp_start()
620 timer_setup(&proto->timer, ppp_timer, 0); in ppp_start()
621 proto->state = CLOSED; in ppp_start()
623 ppp->protos[IDX_LCP].pid = PID_LCP; in ppp_start()
624 ppp->protos[IDX_IPCP].pid = PID_IPCP; in ppp_start()
625 ppp->protos[IDX_IPV6CP].pid = PID_IPV6CP; in ppp_start()
660 switch (ifr->ifr_settings.type) { in ppp_ioctl()
662 if (dev_to_hdlc(dev)->proto != &proto) in ppp_ioctl()
663 return -EINVAL; in ppp_ioctl()
664 ifr->ifr_settings.type = IF_PROTO_PPP; in ppp_ioctl()
665 return 0; /* return protocol only, no settable parameters */ in ppp_ioctl()
669 return -EPERM; in ppp_ioctl()
671 if (dev->flags & IFF_UP) in ppp_ioctl()
672 return -EBUSY; in ppp_ioctl()
676 result = hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); in ppp_ioctl()
685 spin_lock_init(&ppp->lock); in ppp_ioctl()
686 ppp->req_timeout = 2; in ppp_ioctl()
687 ppp->cr_retries = 10; in ppp_ioctl()
688 ppp->term_retries = 2; in ppp_ioctl()
689 ppp->keepalive_interval = 10; in ppp_ioctl()
690 ppp->keepalive_timeout = 60; in ppp_ioctl()
692 dev->hard_header_len = sizeof(struct hdlc_header); in ppp_ioctl()
693 dev->header_ops = &ppp_header_ops; in ppp_ioctl()
694 dev->type = ARPHRD_PPP; in ppp_ioctl()
700 return -EINVAL; in ppp_ioctl()
721 MODULE_DESCRIPTION("PPP protocol support for generic HDLC");