CA2144154A1 - Virtual network using asynchronous transfer mode - Google Patents

Virtual network using asynchronous transfer mode

Info

Publication number
CA2144154A1
CA2144154A1 CA002144154A CA2144154A CA2144154A1 CA 2144154 A1 CA2144154 A1 CA 2144154A1 CA 002144154 A CA002144154 A CA 002144154A CA 2144154 A CA2144154 A CA 2144154A CA 2144154 A1 CA2144154 A1 CA 2144154A1
Authority
CA
Canada
Prior art keywords
atm
port
mac
struct
ret
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Abandoned
Application number
CA002144154A
Other languages
French (fr)
Inventor
John Lindsay Burnett
Peter Newman
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Network Equipment Technologies Inc
Original Assignee
Individual
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Individual filed Critical Individual
Publication of CA2144154A1 publication Critical patent/CA2144154A1/en
Abandoned legal-status Critical Current

Links

Classifications

    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04LTRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
    • H04L49/00Packet switching elements
    • H04L49/35Switches specially adapted for specific applications
    • H04L49/354Switches specially adapted for specific applications for supporting virtual local area networks [VLAN]
    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04LTRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
    • H04L49/00Packet switching elements
    • H04L49/20Support for services
    • H04L49/201Multicast operation; Broadcast operation
    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04QSELECTING
    • H04Q11/00Selecting arrangements for multiplex systems
    • H04Q11/04Selecting arrangements for multiplex systems for time-division multiplexing
    • H04Q11/0428Integrated services digital network, i.e. systems for transmission of different types of digitised signals, e.g. speech, data, telecentral, television signals
    • H04Q11/0478Provisions for broadband connections
    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04LTRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
    • H04L12/00Data switching networks
    • H04L12/54Store-and-forward switching systems 
    • H04L12/56Packet switching systems
    • H04L12/5601Transfer mode dependent, e.g. ATM
    • H04L2012/5638Services, e.g. multimedia, GOS, QOS
    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04LTRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
    • H04L12/00Data switching networks
    • H04L12/54Store-and-forward switching systems 
    • H04L12/56Packet switching systems
    • H04L12/5601Transfer mode dependent, e.g. ATM
    • H04L2012/5638Services, e.g. multimedia, GOS, QOS
    • H04L2012/564Connection-oriented
    • H04L2012/5642Multicast/broadcast/point-multipoint, e.g. VOD
    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04LTRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
    • H04L49/00Packet switching elements
    • H04L49/25Routing or path finding in a switch fabric

Abstract

Asynchronous Transfer Mode Local Area Network (ATM LAN). The ATM LAN is implemented as a set of MAC entities which share a common group address space for the purposes of establishing multicast connections. Each station (10-0) has one or more ATM MAC entities (20-0, 20-1) per physical connection to an ATM network (11). The network ATM LAN service provides the station with ATM LAN configuration information needed for ATM MAC operation. Included in this information is the num-ber of ATM LANs the network has configured for that station.

Description

W094/07316 2 ~ ~ ~ 1 5 4 PCT/US93/08674 .

VIRTUAL NETWORK USING ASYNCHRONOUS TRANSFER MODE
BACKGROUND OF THE lN V~N'l'lON
The present invention relates to networks and particularly to networks of computers that cnmmlln;-', cate data and other information.
Wide Area Networks.
With the increased bandwidth available through transmission ch~nnels, for example increases from T1 to T3, and with the increase in bandwidth provided by bro~h~n~ services such as SONET, larger enterprises are evaluating new applications which require higher speed comml~n;cations. These new applications will dramatically enhance business productivity, but will re~uire vastly improved network control and manage-ment facilities. However, neither private networks nor common carriers have fully addressed the emerging needs of the new comml~n;cation environment.

Computer Networks In the computer field, in order for users to have access to more information and to greater resources than those available on a single computer, computers are connected through networks.
In a computer network, computers are separated by distance where the magnitude of the distance has a significant bearing on the nature of c~mml~n;cation between computers. The distance can be short, for example, within the same computer housing (internal bus), can be somewhat longer, for example, extending outside the computer housing but within several meters (external bus), can be local, for example, within several hundred meters (local area networks, ~ LANs), within tens of miles (metropolitan area networks, MANs) or can be over long distances, for example, among different cities or different conti-nents (wide area networks, WANs).

W094/07316 ~ 5 11 PCT/US93/08674 Multi-~ayer Co~mlln;cation Architecture For networks, the comm~n;cation facilities are viewed as a group of layers, where each layer in the group is adapted to interface with one or more adja-cent layers in the group. Each layer is responsiblefor some aspect of the intended cnmmlln;cation. The number of layers and the functions of the layers differ from network to network. Each layer offers services to the adjacent layers while isolating those adjacent layers from the details of implementing those services. An interlayer interface exists between each pair of adjacent layers. The interlayer interface defines which operations and services a layer offers to the adjacent layer. Bach layer performs a collection of well-defined functions.
Many multi-layered comm~ln;cation architectures exist including Digital Equipment's Digital Network Architecture (DNA), IBM's System Network Architecture (SNA) and the International St~n~rds Organization (ISO) Open System Interface (OSI).
The ISO architecture is representative of multi-level architectures and consists of a 7-layer OSI
model having a physical link layer, a data link layer, a network layer, a transport layer, a session layer, a presentation layer, and an application layer.
In the OSI model, the physical layer is for st~n~Ardizing network connectors and the electrical properties required to transmit binary l's and O's as a bit stream. The data link layer breaks the raw bit stream into discrete units and exchanges these units using a data link protocol. The network layer per-forms routing. The transport layer provides reli-able, end-to-end connections to the higher layers.
The session layer enh~nces the transport layer by adding facilities to help recover from crashes and other problems. The presentation layer st~n~rdizes
2~4~S~
--.3--the way data structures are described and represent-ed. The application layer includes protocol handling needed for file transfer, electronic mail, virtual t~rm;n~l, network management and other applications.
In the n-layer multi-layer models, layers 1, 2, ..., n are assumed to exist in each host computer.
~ayers 1, 2, ..., n in one host computer appear to commnn;cate with peer layers 1, 2, ..., n, respec-tively, in another host computer. Specifically, layer 1 appears to c~mmlln;cate with layer 1, layer 2 appears to commlln;cate with layer 2 and 80 on with layer n appearing to commlln;cate with layer n. The rules and conventions used in c~mmnn;cations between the peer layers are collectively known as the peer level protocols. Each layer executes processes unique to that layer and the peer processes in one layer on one computer station appear to c~mmlln;cate with corresponding peer processes in the same layer of another computer station using the peer protocol.
Although peer layers appear to commlln;cate directly, typically, no data is directly transferred from layer n on one computer station to layer n on another computer station. Instead, each layer n passes data and control information to the n-1 layer ;mme~;~tely below it in the same computer station, until the lowest layer in that computer is reached.
The physical medium through which actual c~mmlln;ca-tion occurs from one computer station to another exists below the top layer n and typically below the bottom layer 1.
In order to provide cnmmlln;cation to the top layer n of an n-layer network, a message, M, is produced by a process running in a top layer n of a source computer station. The message is passed from layer n to layer n-1 according to the definition of the layer n/n-1 interface. In one example where n equals 7, layer 6 transforms the message (for exam-W O 94/07316 PC~r/US93/08674 2 1 4 ~

ple, by text compression), and then passes the new message, M, to the n-2 layer 5 across the layer 5/6 interface. ~ayer 5, in the 7 layer example, does not modify the message but simply regulates the direction of flow (that is, prevents an incoming message from being hAn~eA to layer 6 while layer 6 is busy h~n~;ng a series of outgoing messages to layer 5).
In many networks, there is no limit to the size of messages accepted by layer 4, but there is a limit imposed by layer 3. Consequently, layer 4 must break up the incoming messages into smaller units, prefix-ing a hea~pr to each unit. The header includes control information, such as sequence numbers, to allow layer 4 on the destination computer to put the pieces back together in the right order if the lower layers do not maintain sequence. In many layers, h~A~rs also contain sizes, times and other control field Layer 3 decides which of the outgoing lines to use, attaches its own headers, and passes the data to layer 2. Layer 2 adds not only a header to each piece, but also a trailer, and gives the resulting unit to layer 1 for physical transmission. At the destination computer, the message moves upward, from lower layer 1 to the upper layers, with ~ ers being stripped off as it progresses. None of the headers for layers below n are passed up to layer n.

Virtual Peer To Peer Commun;cation An important distinction exists between the virtual and actual comml~n;cation and between proto-cols and interfaces. The peer processes in source layer 4 and the destination layer 4, ~or example, d interpret their layer 4 commlln;cation as being "direct" using the layer 4 protocol without recogni-tion that the actual commlln;cation transcends down source layers 3, 2, 1 across the physical medium and WO94/07316 2 1 ~ PCT/US93/08674 thereafter up destination layers 1, 2, and 3 before arriving at destination layer 4.
The virtual peer process abstraction assumes a model in which each computer station retains control over its domain and its comml~n;cation facilities within that domain.

Commlln;cation Networks Generally For more than a century, the primary interna-tional cnmml~n;cation system has been the telephonesystem originally designed for analog voice transm-ission. The telephone system (the public switched network) is a circuit switching network because a physical connection is reserved all the way from end to end throughout the duration of a call over the network. The telephone system originally sent all its control information in the 4 kHz voice ch~nn~
using in-band signaling.
To eliminate problems caused by in-band signal-ing, in 1976 AT&T installed a packet switchingnetwork separate from the main public switched network. This network, called C~mmon Ch~nn~l Inter-office Signaling (CCIS), runs at 2.4 kbps and was designed to move the signaling traffic out-of-band.
With CCIS, when an end office needed to set up a call, it chose a ch~nnel on an outgoing trunk of the public switched network. Then it sent a packet on the CCIS network to the next switching office along the chosen route telling which ch~nnel had been allocated. The next switching office acting as a CCIS node then chose the next outgoing trunk ~h~nnel~
and reported it on the CCIS network. Thus, the management of the analog connections was done on a separate packet switched network to which the users had no access.
The current telephone system has three distinct components, namely, the analog public switched 2 1 ~

network primarily for voice, CCIS for controlling the voice network, and packet switching networks for data.

Future Comm~n'cation Networks-ISDN
User d~m~n~ for improved cnmmlln;cation ~ervices have led to an international undertaking to replace a major portion of the worldwide telephone system with an advanced digital system by the early part of the twenty-first century. This new system, called ISDN (Integrated Services Digital Network), has as its primary goal the integration of voice and nonvoi-ce services.
The investment in the current telephone system is so great that ISDN can only be phased in over a period of decades and will necessarily coexist with the present analog system for many years and may be obsolete before completed.
In terms of the OSI model, ISDN will provide a physical layer onto which layer~ 2 through 7 of the OSI model can be built.

Telephone Network Domains In a telephone network, the system architecture from the perspective of the telephone network is viewed pre~om;n~ntly as a single ~omA;n When commu-nication between two or more callers (whether people or computers) is to occur, the telephone network operates as a single physical layer ~om~;n Commun;cation Network Architectures Most wide area networks have a collection of end-users commlln;cating via a subnet where the subnet may utilize multiple point-to-point lines between its node~ or a single common broadcast ch~nn~l.
In point-to-point ~h~nnelsl the network contains numerous cables or leased telephone lines, each one WO94/07316 2 ~ PCT/US93/08674 .

connecting a pair of nodes. If two nodes that do not share a cable are to commlln;cate, they do so indi-rectly via other nodes. When a message (packet), is sent from one node to another via one or more inter-5 m~ te nodes, the packet is received at each inter-mediate node in its entirety, stored there until the required output line is free, and then forwarded. In broadcast channels, a single commlln;cation ch~nnel iS
shared by all the computer stations on the network.
Packets sent by any computer station are received by all the others. An address field within the packet specifies the intended one or more computer stations.
Upon receiving a packet, a computer station checks the address field and if the packet is intended only for some other computer station, it is ignored.
Most local area networks use connectionless protocols using shared medium where, for example, all de~tination and source information is included in each packet and every packet is routed autonomously with no prior knowledge of the connection required.
In the above-identified application CONCURRENT
MULTI-CHANNEL SEGMENTATION AND REASSEMBLY PROCESSORS
FOR ASYNCHRONOUS TRANSFER MODE (ATM) an apparatus for concurrently processing packets in an asynchronous transfer mode (ATM) network is described. Packets that are to be transmitted are segmented into a plurality of cells, concurrently for a plurality of ch~nn~l S, and the cells are transmitted over an asynchronous transfer mode (ATM) channel. Cells 30 received from the asysnchronous transfer mode (ATM) - channel are reassembled into packets concurrently for the plurality of ch~nn~ls.
-Accordingly, there is a need for new networks which satisfy the emerging new requirements and which 35 provide broadband circuit switching, fast packet switching, and intelligent network attachments.

-WO94/07316 2 1 ~ ~ ~ 5 ~ PCT/US93/08674 SUMM~RY OF lNV~NllON
The present invention i8 an Asynchronous Trans-fer Mode ~ocal Area Network (ATM LAN). The ATM ~AN is implemented as a set of MAC entities which share a common group address space for the purposes of estab-lishing multicast connections. Each station has one or more ATM MAC entities per physical connection to an ATM network. The network ATM LAN service provides the station with ATM LAN configuration information needed for ATM MAC operation. Included in this information is the number of ATM ~ANs the network has configured for that station.
In the present invention, a comml1n;cation system includes an ATM network. The ATM network has a plurality of ports, each port having a unique port address. The ATM network includes one or more ATM
switches for connecting sending ports to receiving ports.
The cnmml1n;cation system includes a plurality of stations, each station having a unique station address distingl1;~h;ng the station from other sta-tions. Each station is connected to ~he ATM network at a port whereby source stations comml~n;cate with destination stations. Bach station provides packets for transferring information, information includin~
a destination station address, for addressing desti-nation stations. Each station includes a packet converter for converting between packets and cells for transfers between stations.
The c~mmlln;cation system provides address resolution for determ;n;ng a port address corre-sponding to a destination station address. The address resolution includes multicast for multicast-ing the destination station address to a group of stations.
The cnmm11n~cation system provides manage-ment for requesting connections through the ATM

W O 94/07316 21 4 ~ I 5 1 PC~r/US93/08674 _ q,_ network connecting sending ports to receiving ports whereby packets are transferred from source stations to destination stations by cell transfers through ATM
network.
ATM LANs may are extended by bridging several ATM LANs together using transparent MAC bridges and routers.
Permanent virtual connections or switched virtual connections may underlie the layer manage-ment.
The commlln;cation system operates with a multi-level architecture, such as the ISO architec-ture, and Logical Link Control (LLC), Media Access Control (MAC) and addressing functions are performed for ATM LANs. An ATM LAN provides support for the LLC sublayer by means of a connectionless MAC sublay-er service in a m~nner consistent with other IEEE 802 local and metropolitan area networks. The ATM LAN
interface is built on the user-to-network interface for ATM and adaptation layers.
The cnmmlln;cation system including the ATM
LAN provides the following benefits:
Physical plug-in locations can be moved and changed without changing logical locations.
The stations in the cnmmlln;cation system are partitionable into multiple work groups.
The cQmmlln; cation system provides high bandwidth that supports mult;mP~;~ applications including voice, video, real-time and time-sensitive applica-tions.
The comml~n;cation system integrates Wide Area Networks (WAN) and Local Area Networks (LAN) into one system.
The foregoing and other objects, features and advantages of the invention will be apparent from the following detailed description in conjunction with the drawings.

WO94/07316 . PCT/US93/08674 2 1 ~

BRIEF DESCRIPTION OF THE DRAWINGS
FIG. 1 depicts a number of user stations con-nected together in an ATM network system.
FIG. 2 depicts the multi-level protocol used to connect two or more stations in the ATM network system of FIG. 1.
FIG. 3 depicts the network layer and the data link layer connected to a ATM interface in the ATM
network system of FIGs. 1 and 2.
FIG. 4 depicts details of the ATM MAC sublayer and the ATM interface for stations of FIGs. 1 and 2.
FIG. 5 depicts details of the ATM LAN Server and the ATM interfaces of the network of FIGs. 1 and 2.
FIG. 6 depicts three ATM LANs configured on a three-switch ATM network.
FIG. 7 is a representation of the details of the ATM MACs of stations S0, S1, S2 and S3 from FIG. 6.

W094/07316 2 ~ 4 1 1 ~ ~ PCT/US93/08674 DETAILED DESCRIPTION
In FIG. 1, an ATM network system is shown in which two or more computer stations 10 are intercon-nected by an ATM network 11 for network commllnlca-tion. The stations 10 include the station S0, S1, ..., Ss designated 10-0, 10-1, ..., 10-s. The ATM
network system of FIG. 1 employs, for example, the top six of the seven OSI model layers. The OSI model physical layer 1 is replaced with a ATM interface 10which operates in an asynchronous transfer mode (ATM) in accordance with the B-ISDN protocol.
In FIG. 2, the ATM network 11 connects, by way of example, the S0 station 10-0 to the S1 station 10-1. The S0 station 10-0 includes the top six OSI
15layers, namely, the application layer [0, 7], the presentation layer [0, 6], the session layer [0,5]
and the transport layer [0,4]. The layers 7 through 4 in FIG. 2 are designated as the higher layers and operate in the conventional m~nner for the OSI model.
20In FIG. 2, the S0 station 10-0 includes the network layer [0,3] and the data link layer, [0, 2].
The data link layer [0,2] includes the logical link control (LLC) sublayer and the media access control (MAC) sublayer. The MAC Rublayer in the data link 25layer [0, 2] connects to a ATM interface 13-0. The ATM interface 13-0 operates in accordance with the B-ISDN protocol defined by the CCITT.
In FIG. 2, the S1 station 10-1 has the higher layers including the application layer [1,7], the 30presentation layer [1,6], the session layer [1,5] and the transport layer [1,4]. The S1 station 10-1 also includes the network layer [1,3] and the data link layer [1,2] that connects to the ATM interface 13-1.
In FIG. 2, the ATM interface 13-0 for the S0 station 3510-0 and the ATM interface 13-1 for the S1 station 10-1 connect to a ATM switch 13' in the ATM network 11. The ATM interfaces 13-0 and 13-1 and ATM switch W O 94/07316 PC~r/US93/08674 2 1 ~

13' operate in accordance with an ATM architecture for ATM commllnlcationn. The ATM LAN commllnlcation is under control of an ATM LAN server 12 in the ATM
network 11.
In FIG. 2 each of the higher layers in the S0 station 10-0 and in the S1 station 10-1 function in a well known manner in accordance with the OSI model.
Also, the network layer [0, 3] in the S0 station 10-0 and the network layer [1, 3] in the S1 station 10-1 conform to the model OSI The data link layer [0,2 in the S0 station 10-0 and the data link layer [1,2] in the S1 station 10-1 have OSI compatibility. The compatibility with the OSI model at the data link layer enables the ATM network system of FIGs. 1 and 2 to be compatible with other local area networks and other networks that conform to the OSI model from layer [2] and above. Below the OSI layer [2], the c~mmlln;cation and connections are compatible with the B-ISDN model of the CCITT.
The FIG. 2 c~mmlln;cation network system is a hybrid of the OSI model above layer [1] and asynchr-onous transfer mode below the data link layer [2].
In FIG. 3, further details of the S0 station 10-O are shown and are typical of all of the other stations 10-1, ... , 10-s of FIG. 1. In FIG. 3, the higher layers 7, 6, 5 and 4 are conventional.
Typically the higher layers of the station 10-0 of FIG. 3 are implemented on a processor such as a Sun Workstation.
In FIG. 3, the network layer [3] uses any one of a number of st~n~rd protocols such as the IP proto-col 15, the DEC NET protocol 16, the OSI protocol 17 or the XNS protocol 18. Any other protocol can be implemented in the network layer 3.
In FIG. 3, the data link layer [2] includes the LLC sublayer and the MAC sublayer. The LLC sublayer includes the Logical Link Control (LLC) 19 which is WO94/07316 21 ~ PCT/US93/08674 conventional in the data link layer of the OSI model.
The data link layer [2] also includes the MAC
sublayer which as a component of the data link layer [2]. The MAC sublayer typically may include other MAC sublayers in accordance with the st~n~rds IEEE
802.3, 802.4, 802.5, 802.6 and FDDI. ATM LANs are, therefore, capable of interoperating with a wide variety of media. ATM LANs interoperate with all IEEE 802 Local Area Networks and Metropolitan Area Networks using transparent bridges and routers.
Stations connected to ATM LANs comml~n;cate with stations connected to any IEEE 802 LAN or MAN via a bridge.
In accordance with the present invention, the data link layer [2] also includes a new ATM MAC
sublayer 22 analogous to the other MAC sublayers 23.
The ATM MAC sublayer 22 differs from the other MAC
sublayers 23 in that the ATM MAC sublayer 22 commlln;-cates with the ATM switch 13 for ATM cnmm~]n;cation.
In FIG. 3, the ATM MAC sublayer 22 includes one or more ATM MACs including, for example, ATM MAC 0, ATM MAC 1, ..., ATM MAC M designated 21-0, 21-1, ....
21-M respectively. Each of ATM MACs 21-0, 21-1,....
21-m defines an ATM local area network (ATM LAN).
The ATM MACs of the ATM MAC sublayer 22 connect between the logical link control 19 and the ATM
interface 13-0. The control of which of the stations (like the stations 10-0, 10-1,..., 10-s) are serviced by particular ones of the ATM MACs 21 of FIG. 3 is determ; n~ by the station management 20 within the ATM MAC sublayer 22. Other stations (or the same stations) may also be serviced by other local area networks such as Ethernet under control of the other MAC sublayers 23.
In FIG. 3, the ATM MAC sublayer is capable of servicing the commlln;cation requirements of the stations 10-0 through 10-s of FIG. 1 in one or more W O 94/07316 PC~r/US93/08674 2 ~

ATM LANs. Stations can be switched from one ATM LAN
to another ATM LAN under control of station manage-ment 20 without requirement of modifying the physical connection to the station. For this reason, the ATM
LANs are virtual LANs.
In FIG. 4, further details of the ATM MAC
sublayer 22 and the ATM interface 13-9 of FIG. 3 are shown.
In FIG. 4 the ATM MAC sublayer includes the station management 20 and the ATM MACs including the ATM MAC 0, ..., ATM MAC M designated as 21-0, ....
21-M.
In FIG. 4, the ATM MAC 0 includes the multicast address resolution 24, the unicast address resolution 25, the frame 26 and the connection management 27.
In FIG. 4, the ATM interface 13-0 includes the signaling protocol 28 in the control plane, the ATM
ADAPTATION ~AYER (A~L) 29, the ATM layer 30 and the physical layer 31.

W O 94/07316 ~ 5 4 PC~r/US93/08674 -1~- , .
1 ATM LANs 1.1 Introduction In FIG. 3, the higher layers [7,6,5,5] and [3]
are conventional while the data link layer [2] in-cludes the LLC sublayer and the ATM MAC sublayer toimplement the Asynchronous Transfer Mode Local Area Networks (ATM LANs). Such an implementation is provided with newly defined Media Access Control (MAC) including addressing protocols. The ATM LAN
provides support for the LLC sublayer by means of connectionless M~C sublayer service in a manner consistent with other IEEE 802 local area networks (LAN) and metropolitan area networks (MAN). The ATM
LAN interface is built on the user-to-network inter-face for the ATM layer and the ATM adaptation layer(AAL).
An ATM LAN includes a set of MAC entities which share a common group address space for the purposes of establishing multicast connections. Each station has one or more ATM MAC entities per physical connec-tion to an ATM network. The network ATM LAN ~ervice provides the station with ATM LAN configuration information needed for ATM MAC operation. Included in this information is the number of ATM LANs the network has configured for that station.
The user-to-network interface at the LLC and MAC levels is defined for the ATM LAN Architecture in a mAnn~r analogous to other Data Link Layer architec-tures.
1.3 ATM LAN Functionality An ATM LAN has the following characteristics:
addressing- all LANs connected by MAC
bridges use 48 bit addressing unicast- all stations can send fra-mes to any other station in the LAN

W O 94/07316 PC~r/US93/08674 21~15~ 1~

duplication- frames are not duplicated broadcast- all stations can broadcast to every other station in a LAN
multicast- any station can send to any group address and any station can register to receive frames for any group address promiscuity- any station may chose to receive all ~rames with group destination addre ses 1.4 ATM LANs An ATM LAN is a local network having a set of stations which share a common group address space for the purpose of establishing multicast connections.
An ATM LAN is implemented using services of ATM LAN
MAC, ATM signaling and ATM Adaptation Layers.
Stations may participate in more than one ATM LAN.
ATM LANs may be bridged together using MAC bridges.
ATM LANs are sometimes called Virtual LANs because they are not limited by the limitations of any physical m~ characteristics. A single under-lying ATM network may support many ATM LANs. A
station with a single ATM interface may be connected to many separate ATM LANs. There are no inherent limitations in the ATM LAN protocol itself to re-strict either the physical extent or the number of stations in a particular ATM LAN. Practical limita-tions, such as multicast traffic, usually limit the size and scope of ATM LANs.
ATM LAN8 interoperate with a wide variety of me~;~. ATM LANs can interoperate with all IEEE 802 Local Area Networks and Metropolitan Area Networks using transparent bridges and routers. Stations connected to ATM LANs are able to cnmmlln;cate with stations connected to any IEEE 802 LAN/MAN connected via bridge.

W O 94/07316 2 ~ 4 ~ PC~r/US93/08674 .

2 ATM LAN Architecture 2.1 Overview An ATM LAN includes a set of procedures and protocols which work together to provide the services found in IEEE 802 LANs. The A~L and ATM protocols defined by CCITT are augmented by the ATM LAN MAC
layer which maps unacknowledged MAC PDUs (MAC Proto-col Data Units) onto unacknowledged A~L PDUs trans-mitted over virtual connections provided by the ATM
physical layer. The ATM MAC manages connections using an ATM signaling protocol.
2.2 Logical Link Control Stations must comply with 802.2 Type I specifi-cation which is defined by ISO 8802. This includes m~n~tory response to XID (Exchange ID) and Test cqmm~ntl~, When SNAP encapsulations are defined for upper layer protocols they are used.
2.3 Station ATM LAN MAC
Each station has one ATM LAN module per physical ATM interface. Each ATM LAN module provides MAC
services via one or more ATM MAC entities. The ATM
LAN server provides the ATM LAN MAC with config-uration parameters.
2.3.1 ATM MAC Functions The ATM MAC layer provides the following func-tions:
ATM LAN Configuration- det~rm; n~s the number of ATM LANs which have been configured for the station and the operational parame-~ ters needed to establish multicast connections for each ATM LAN.
MAC PDU Framing- MAC SDUs (Service Data Units) are encapsulated in 2 ~

an A~L specific framing.
Address Resolution-IEEE 802. 48 bit M~C
addres~es are mapped onto E.164 ATM addresses.
Connection Management- establishes and rele-ases virtual connections for transmission of M~C
PDUs (Protocol Data Units) and reception of frames ad-dressed to registered group (multicast) addre~ses.
Multicast Service-protocol and procedur-es are defined for trans-mission and reception of frames with group address-es. The network provides unreliable delivery via multicast service. The interface to the multicast service is A~L xpecific.
The interface to be used is determined by configuration management.
2.3.2 ATM MAC Entity Service Interface The ATM MAC entity provides the following service interface to MAC users.
Primitive Parameters M_UNITDATA.request destination address source address mac ~er~ice data unit M_UNITDATA.indication destination address source address mac service data unit M_REGISTER_ADDRESS group address M_UNREGISTER_ADDRESS group address M_REGISTER_ALL
M_UNREGISTER_ALL

W O 94/07316 2 1 ~ ~ 1 5 ~ PC~r/US93/08674 . , j ~., -t~-2.4 ATM Adaptation Layer The adaptation layers provide transmission and reception of frames on virtual connections. The stAn~Ard CCITT AAL are used. In this application, AAL 3 is used to denote AAL 3/4 when end systems A negotiate the use of the multiplexing identifier.
AAL 4 is used to identify AAL 3/4 when the multiple-xing identifiers used are specified by the network.
IEEE 802.2 LLC will be identified by a value of 1 in the protocol id field of A~L 3/4 frames.
2.5 ATM Signaling Protocol The ATM LAN signaling protocol contains a subset of the functions in Q.93B. It provides the following services:
o establishment of virtual connections (VCs) o negotiation of the upper layer protocol (ULP) o clearing of connections o dynamic port address assignment o user to network keep alive 2.6 ATM LAN Server The ATM I AN server provides con~iguration and multicast services. It provides operational parame-ters for each ATM LAN in which each ATM station is configured. Membership in ATM LANs is controlled via policies implemented by the server. These policies may vary between ATM LAN providers. The ATM LAN
configuration protocol defines the information provided by stations with which servers may implement policies. Two policies which can be implemented are "port based configuration" and "station based config-uration". The ATM LAN server may use the physical cabling to det~rm;nP LAN membership. This is called "port based configuration~. Alternatively, the ATM
LAN server may use station MAC addresses to determine LAN membership. This is called "station based configuration~. The same station to server protocol is used in either case. The station is not affected W O 94/07316 PC~r/US93/08674 2 1 4 ~

by the configuration policies implemented. When requesting ATM LAN configuration parameters, the station always provides its MAC address(es).
The station table shown below is an example of the station-based configuration for the system shown in FIG. 6. The port table shown below is an example of port-based configuration for the system shown in FIG. 6.
STATION TABLE
(VLAN MEMBERSHIP) V AN MAC ADD-ESS
VLAN1 MAC_Add 0](S0),MAC_Add[l](Sl),MAC_Add[5](S5)...
VLAN2 MAC_Add:2](S2),MAC_Add[6](S6)...
VLAN3 MAC_Add[0](S0),MAC_Add[3](S3),MAC_Add[4](S4) PORT TABLE
(VLAN ASSOCIATION) Port Addresses rs/p#] V~AN
PA [2,2], PA [2,3], PA [2,4], PA [2,5] VLAN [3]
PA [2,6], PA [2,7], PA [2,8], PA [2,9] VLAN [2]

PA [2,3], PA [3,4] VLAN [3]

Each station establishes a VC to an ATM LAN server for each physical interface. A well known group address is used. If r~lln~nt ATM LAN servers are providing configuration and multicast service, this service is transparent to the ATM station. The servers agree amongst themselves which ones will serve any particular station. The servers may elect to distribute responsibility for multicast service over several servers. This election is transparent to the station.
3. ATM LAN Configuration Management A station may belong to one or more distinct ATM
LANs. The station will then have been configured with one or more MAC entities each having a unique W O 94/07316 2 1 ~ ~ 1 5 ~ PC~r/US93/08674 -2t -MAC address.
At power-on, the station establishes a VC to the network ATM LAN server. The station ATM MAC sends a configuration enquiry to the ATM LAN server. The enquiry contains the station's MAC address, alan_mac.
struct alan_req { /* configuration request */
u_char alan_proto;
u_char alan pdu_type;
u_short alan_seqnum;
struct atm_addr alan_mac;
} ;
Using the unique MAC address, alan_mac, the ATM
LAN server determ;n~s the number of ATM LANs config-ured for that station and the configuration for each connected ATM LAN. A configuration response is sent to the station.
struct alan_config {
u_char alan proto;
u_char alan_pdu_type;
u_ short alan_seqnum;
int alan_num_lans;
struct alan_parms alan_lan[];
} ;
The configuration response contains one alans Pa-rms per ATM LAN. For each ATM LAN the configuration manager activates an ATM MAC entity. The parameters in the alan_parms element control the configuration parameters of each ATM LAN "tap".
Each ATM LAN 'tap' is described by the following parameters. The alan_config and alan_update messages contain one or more alan_parms structures.
struct alan_parms {
int alan_version;
int alan_aal;
struct atm_addr alan_port;
struct atm_addr alan_mcast_base;
struct atm_addr alan_lan_uid[];

W O 94/07316 PC~r/US93/08674 21~15~ ~

int alan_num_mcast;
u_short alan_mid;
u_short alan_mtu;
}i ..
5The alan_aal parameter specifies which A~ is used for multicast frames. Currently defined values are
4 and 5 for A~s 4 and 5 respectively. The alan_port is the port address from which VCs are setup for this ATM LAN. The ATM LAN server may specify different 10port addresses for different taps or may specify the same for all. The ATM MAC entity treats this E.164 address as an unstructured bit string.
The ATM LAN manager allocates a range of E.164 group address space for each ATM LAN. The al-15an_mcast_base is E.164 group address which is used in conjunction with alan_num_mcast (the number of group addresses allocated to the ATM LAN) to map IEEE 802.1 group addresses onto the E.164 group address space.
AA~ and multicast service parameters are protocol 20specific.
A~L multicast service requires that multicast AAL
PDUs be transmitted using multiplexing identifiers, (MIDs), provided by the ATM LAN server. This allows multicast service to be provided via replication 25functions often found in ATM switch fabrics. Each ATM MAC entity is assigned a LAN unique MID for transmission and must reassemble AA~ using the full 10 bit MID.
Each ATM LAN is assigned a globally unique identi-30fier, alan_lan_uid. This is a 128-bit name created by the ATM LAN server. The ATM ~AN server provides alan_parms structures for the requested MAC address-es. If the station requests configuration parameters for two MAC addresses which belong to the same ATM
35LAN, two identical alan_parms elements are returned.
Once the ATM MAC entities have been created, the configuration manager periodically sends keep alive WO94/07316 PCT/US93/~8674 21~15~

frames on the configuration SVC. If the configura-tion SVC is released the configuration manager destroys the ATM LAN entities it created. If after some number of retries the ATM LAN server does not respond to keep alive packets, the configuration manager will release the configuration SVC and destroy ATM MAC entities.
Configuration Acquisition Protocol State Machine Sta~e Event Actions Newstate Inactive Activate Setup Request Wait for Setup Start timer C1 Conf Wait for Release Setup Request, Wait for Setup Setup Conf Ind Start timer C1 Conf Setup Config Request, Wait for Setup Conf Start Timer C2 Conf Wait for Timeout Config Request, Wait for Setup Setup Conf Increment Conf Retries Max Release, Wait for Setup retries Setup Request Conf Config Activate Active Resp MAC Entities 30 Any state Deactiv- Deactive active Inactive ~Active ate MAC entities, Release config-uration VC
Release Setup Request, Setup Request, Ind Start timer C1 Start timer C1 4. ATM LAN MAC
The ATM MAC maps IEEE 802.1 flat 48 bit addresses to 60 bit hierarchical E.164 ATM addresses by the address resolution function. Individual IEEE 802.
addresses are mapped into port addresses via the ATM
Address Resolution Protocol, ATM ARP. Group IEEE
802.1 addresses are mapped to ATM group addresses using a fixed algorithm.
Once an ATM address is det~rm- n~, the ATM signal-ing protocol is used to establish a virtual connec-21 ~41~ -2~-tion. The connection is either a unicast connection or a multicast connection depending upon whether the ATM address is an individual or group address.
Connection management is responsible for establishing and clearing these connections.
Once the appropriate connection has been determined for a frame, it is encapsulated in an A~L specific encapsulation method. AAL 4 and AAL 5 have distinct multicast mechanisms due to the limitations of AAL 5.
4.1 Framing 4.1.1 AAL 3/4 - ATM LAN uses the same MAC framing as 802.6. ATM
LANs use 48 bit MAC addresses to enable interoperab-ility with 802 LANs via MAC bridges. As shown in the following table, addresses are encoded as byte quantities as per 802.6.

COM MCP HEAD HEAD LLC PAD CRC COM

HEAD _ T~AIL
DEST SOUR MC
ADR ADR BITS
4 8 8 4 0-20 0-9188 0-3 0,4 4 Prot Pad QOS Qos CRC Head Bridging ID LEN Delay Loss Ind Ext (Not Used) Len -4.2 Addresses Two types of addresces are used in an ATM LAN, station MAC addresses and ATM (or port) addresses.
Both types of addresses may either be individual or group addresses.
MAC station addresses identify individual sta-tions connected to an ATM LAN. Station addresses are 48 bit universally administered 802.1 MAC addresses.
These MAC addresses enable interoperability with W094/07316 2 ~ PCT/US93/08674 802.lD LAN MAC bridges. Station addresses are used as MAC frame source or destination addresses.
MAC group addresses are used to address frames to multiple destination stations on an ATM LAN. Group addresses are used to set up virtual connections to 4 multiple destination stations without knowledge of those stations' individual addresses. They are used to provide multicast and broadcast services. Broad-cast is a a specific instance of multicast with all stations receiving frames with well defined group address, specifically all l's. Group addresses are 48 bit universally or locally ~m; n; stered 802. MAC
addresses. The group address with all bits set to one is the broadcast address.
ATM Port addresses or port addresses or ATM
individual addresses identify physical ports on switches. They are hierarchical 60 bit E.164 ad-dresses dynamically assigned by the network. Each virtual connection has a port address for at least one endpoint. Port addresses are used in ATM ARP and Signaling PDUs.
ATM group addresses (or multicast port address-es) identify an ATM level multicast group. They are used in signaling PDUs.
AddressTyPe PA~1 n~ Addre~s ATM port llOx no padding 60 bits address ATM group lllx no pA~; ng 60 bits 30address MAC station 1000 12 bits 48 bits address MAC group 1000 12 bits 48 bits address x - indicates whether the address is publicly or privately ~m; n;stered 4.3 Multicast Service 4.3.1 Background Any station on the LAN can register to receive W O 94/07316 .. . PC~r/US93/08674 ~1441~4 frames addressed to specific group addresses. All stations register to receive frames addressed to group address ~ which is defined to be the broadcast group address. Any station can send frames to any group address without the knowledge of which stations want to receive them.
4.3.2 ATM ~AN Multicast In an ATM ~AN, multicast capability is provided by the multicast server which is part of the LAN
server. Stations use that service by establishing virtual connections to the server using the multicast base ATM address provided in the configuration parameters (alan_parms). The multicast base address is a privately ~; n; stered group E.164 address.
Virtual connections with a group ATM address at one endpoint are multicast VCs. When setting up a multicast VC the station may request transmit only access so that it will not receive frames transmitted on that VC.
IEEE 802.1 48 bit addressing provides for up to 246possible group addresses all registered by various stations in one LAN. Few ATM networks could support 246 virtual connections. To bridge this gap in service offering and network capability, each ATM LAN
is configured to support a small (typically 100s) number of multicast circuits. This number is export-ed in the alan_parms configuration element. Each ATM
MAC entity is also provided with a multicast base address which is treated as a 64-bit integer. These two numbers are used to map many 48-bit IEEE group addresses to fewer ATM group addresses which are then used to setup multicast connections. If al-an_num_multicast is zero, then the 48-bit group address is added to alan_mcast_base. Otherwise the 48-bit group address is treated as a 16 most signif-icant bits of the 48-bit group address are Exclusive-Ored into the 32 least-significant bits, the result W094/07316 2 1 ~ ~ 1 5 ~ PCT/US93/08674 }
-2~-is divided by alan_num_mcast and the resulting r~m~; n~Pr is added to alan_mcast_base. In either case, the result value is used as a group address to set up a multicast connection for that group address.
4.3.3 Registering for a group address Each ATM MAC entity maintains a list of group addresses for which its users have requested it receive frames. Each of these group addresses is mapped onto a ATM group address when the MAC entity is given is alan_parms information, that is, when it becomes active. There after, the ATM MAC entity will maintain a multicast connection for each port address derived from the above computations. Note, several MAC group addresses may map onto one group port address. In this case, only one connection is main-tained for those MAC group addresses. If the network releases a multicast connection, the ATM MAC entity will re-establish another one.
The ATM MAC entity will always maintain a multic-ast connection for the group port address derivedfrom the broadcast MAC address. 4.3.4 Transmission of Multicast MAC PDUs When an ATM MAC entity is presented with a M_UNITDATA.request with a group destination address it maps the group MAC address to the group ATM
address, and transmits the MAC PDU on the connection established to that port address. If no connection is already established, the frame is queued until one is established. Multicast connections setup solely for the transmission of multicast PDUs are aged in the same fashion as those setup for unicast PDUs.
4.3.5 Reception of Multicast MAC PDUs The group destination addresses in received MAC
PDUs are checked against the list of registered group addresses. If the group addresses are not regis-tered, the frame is dropped. This dropping is necessary because transmitters may map MAC group W O 94/07316 PC~r/US93/08674 2 1 ~
-2~-addresses onto a multicast connection established to register other group addresses.
All group addressed frames are not received on corresponding multicast connections. Stations listening for multicast frames must be prepared to receive those frames on either the appropriate multicast VC or the broadcast VC.
4.3.6 Unregistering a group address Multicast connections established for registered group addresses are not aged. They are not released until the last MAC service users want to receive frames addressed to any of the group addresses mapped onto that connection.
The ATM MAC entity maintains reference counts on the number of MAC service users which have registered a group address. A reference count on the multicast connection is maint~;ne~ for each MAC group which maps onto the connections group ATM address.
4.3.7 A~L 4 Multicast Service Stations connected to multicast VCs can receive frames from many sources simultaneously. The multi-plexing identifier (MID) in the A~4 SAR header is used to correctly reassemble these frames. MIDs are unique within a given ATM LAN. The ~AN server assigns a unique MID to each port address.
Up to 1023 stations may be connected to an ATM
AAL 3/4 LAN. Each station has a globally unique 48-bit address per ATM LAN. Each station is assigned one MID per ATM LAN (local port address to the station) to be used when transmitting frames on multicast VCs. Stations may not transmit more than one frame simultaneously on multicast VCs with the same local port address. Each station implements MAC
level address filtering for frames received on multicast VCs.
Each station has a multicast filter which is used to filter frames received on broadcast VCs. This WO94/07316 2 1 ~ 4 1 ~ PCT/US93/08674 ', ~ ' .
zq filter may be implemented in hardware or software.
The filter is necessary because each ATM network provides limited multicast service and stations may - broadcast unicast frames.
4.3.8 AAL 5 Multicast Service A~L 5 does not provide for multiplexing frames on a single VC simultaneously. The mid field in the alan_parms structure is ignored. There is no limit on the number of stations (or ATM MACs) which may belong to an AAL 5 ATM LAN.
4.4 ATM Address Resolution Protocol Individual IEEE 802.1 MAC addresses are mapped into port addresses via the ATM Address Resolution Protocol (ATM ARP). Once the port address is deter-mined the ATM signaling protocol is used to establisha virtual connection.
4.4.1 ATM ARP Operation Stations connected directly to ATM LANs will, conceptually, have address translation tables to map MAC addresses (both station and group addresses) into virtual connection identifiers. The MAC-to-port table, provides mappings from MAC addresses to port addresses.
The MAC transmission function accesses this table to get next hop port address given destination station address. This table is updated when new station address to port address mappings are learned via ATM ARP and when MAC group address to ATM group address mappings are computed. The entries in the MAC to port table are updated when ATM ARP requests and replies are received.
When the MAC layer is presented with a frame for transmission, it looks up the destination address in the station to port address table. If an entry is found, connection management selects the appropriate virtual connection upon which the frame should be transmitted.

W O 94/07316 PC~r/US93/08674 2~4~ 30 -If no entry is found, a new entry is allocated for that MAC address. If the MAC address is a group address, an ATM group address is computed using an AAL specific function. This operation permits the broadcast VC to be established without sending ATM
ARP requests. Mapping individual MAC addresses to port addresses is accomplished by broadcasting an ATM
ARP request for the MAC addresses to all stations connected to the ATM LAN. The ATM ARP request carries the senders MAC and port address mapping.
All stations receive the request. The station with the specified MAC address responds with an ATM ARP
reply. The responder updates its MAC-to-port table using the information in the request. The reply carries both the responders' and the requestors MAC
and port addresses. When the requestor receives the ATM ARP reply, it updates its port-to-MAC address table.

MAC to Port entry Station Address 48 Nçxt Hop Port Status Bit 802.1 MAC Address E.164 The requesting station must transmit MAC frames on broadcast connections until it receives responses to its ATM ARP requests. It may then set up a connection using the port address in the reply.
Usually, the responder sets up the connection before replying.
The ATM ARP function times out entries in the MAC-to-port table when they have been idle for some time. Connection management is notified when entries in the MAC-to-port table are added, updated or delet-ed. Connection management notifies ATM ARP when connections are established and released. Entries in this table are deleted when an SVC establishment to the port address fails. They are deleted when the connection corresponding to an entry is released.

W O 94/07316 2 ~ ~ 4 ~ ~ ~ PC~r/US93/08674 .
-3l TABLE 5: Port to VPI-VCI entry Local Port Peer Port OOS VPI/VCI
Address Address 4.4.2 ATM ARP PDUs ATM ARP requests and replies are encapsulated in 802.2 LLC and the appropriate AAL for the connection upon which they are sent. ATM ARP re~uests are always broadcast. Therefore they are encapsulated in the AAL used for multicast connections. ATM ARP
replies are usually sent on point to point connec-tions. The ATM MACs negotiate the AAL to be used for that connection. The reply is then encapsulated in 802.2 LLC and the specific AAL framing.
The ATM ARP messages are:
/*
* ATM Address Resolution Protocol.
*/
struct atm_arp {
u_short aa_llp; /* lower layer protocol */
u_short aa_ulp; /* upper layer protocol */
u_char aa_llp_len;
u_char aa_ulp_len;
u_short aa_msg_type;
u_char aa_sender_port[8];
u_char aa_sender_mac[6];
u_char aa_target_port[8];
u_char aa_target_mac[6];
};
/* aa_msg_type~ s */
#define ATM_ARP_REQUEST
#define ATM_ARP_REPLY 2 ..
The aa_ulp_len and aa_llp_len fields are always 6 and 8 respectively. The aa_ulp field is set to 16.
The sender mac and port addresses are set to the sender's Mac and Port addresses for re~uest and non-proxy reply messages. The aa_send_mac field in W O 94/07316 PC~r/US93/08674 2 1 ~ 4 -3Z-proxy replies contains the aa_target_mac from the corresponding request. The aa_target_mac is always set to the Mac address needing resolution in requests and it is set to the requestor's Mac address in replies. The aa_target_port is undefined in reguests and in replies it contains the aa_sender_port from the corresponding request. The recipient of a reply verifies that the aa_target_port corresponds to one of its own port addresses.
4.5 Connection Management Once a MAC address has been resolved to a ATM
address a connection to the station receiving frames for that MAC address can be set up and those frames can be transmitted directly to that station rather than broadcast. Connection management is responsible for defining the connection establishment and release policies. The ATM signaling protocol is used to establish connections for ATM LAN MAC frames. A
specific upper layer protocol identifier is reserved for ATM hAN MAC frames.
4.5.1 Connect Establishment Connections are established when an Unacknowl-edged Data Request needs to be transmitted to a MAC
address for which a MAC-to-ATM address mapping is known, but no connection to that ATM address, is established (or emerging). It is possible for two MAC entities to simultaneously establish connections to each other. When connection management receives connection setup SDU from ATM signaling, it checks to see if a connection to the peer port address already exists. If another connection exists (or is being established), the connection initiated from the lower port address is released. Thus there will never be more than one connection established between two ATM
M~C entities.
While a connection is being setup, frames which would be transmitted on that connection once it is W O 94/07316 PC~r/US93/08674 214~
-3~-established must be ~ueued or dropped. Frames should not be broadcast. At least one frame must be queued.
Implementations may chose to queue more. Once the connection is set up, any queued frames are transmit-ted. The first frame transmitted on a connection initiated by a station must be the ATM ARP response for the an ATM ARP request.
4.5.2 Quality of Service Currently, distinct qualities of service may be defined for ATM MAC PDUs.
4.5.3 Connection Release Connections for which there is no MAC-to-ATM
address mapping are held for the product of the number of ATM ARP retries and retry interval and then released. The MAC-to-ATM address mappings are aged separately.
When ATM ARP deletes all the translations to a specific ATM address, all connections to that ATM
address are released.
When a connection is released, the ATM ARP
function deletes all MAC to ATM translations for that connection's remote ATM address.
4.6 Frame Reception Frame Reception Stations are responsible for performing filtering of incoming frames. Unicast addressed frames for other stations will be received on the broadcast VC. Multicast frames for unregis-tered multicast addresses may be received on multic-ast VCs. These frames are not passed up to the MAC
service user.
4.7 Address Resolution and Connection Establishment Bxample In this example, the steps are described that are required for one station, called ~yra, to deliver a MAC UNITDATA SDU to another station, called Altera, assuming neither station has had any prior c~mmlln;ca-tion. It is assumed that both stations are part of the same ATM LAN. These steps are only required for W O 94/07316 PC~r/US93/08674 214~
-3~-the initial transmission from Lyra to Altera. Addi-tional MAC PDUs may be transmitted on the connection setup by these steps until either station decides it no longer wishes to maintain the connection. In this example, MAC addresses are expressed in xx:xx:xx:xx-:xx:xx form where each pair of hex digits, xx, is one octet for the address. Port addressees are expressed in the same form except that they have 8 octets.

o An ATM MAC service user on Lyra provides the ATM
MAC with an UNITDATA SDU to be sent to station address 00:80:b2:eO:00:60. The MAC consults its MAC
to port address table, but finds no translation.
o The MAC creates an ATM ARP request for MAC
address 00:80:b2:eO:00:60. The request contains ~yra's own MAC and port addresses, 00:80:b2:eO:00:50 and dl:41:57:80:77:68:00:02 respectively. The ATM ARP
is encapsulated in LLC/SNAP. The destination MAC
address is ff:ff:ff:ff:ff:ff (the broadcast address).
The ATM MAC recursively invokes itself to transmit the ATM ARP request.

o The MAC address to port address table is search-ed for the broadcast MAC address and the correspond-ing port address is obtained, fl:41:57:80:77:68:01:-01. The station established a connection to this port address when the ATM ~AN M~C entered the active state. The ATM ARP PDU is encapsulated in an 802.6 frame and passed to the A~L 4 function along with the MID associated with this ATM MAC entity for transmis-sion of that multicast connection.

o The M~C must transmit the MAC SDU. In lieu of a valid MAC address to port address mapping the broad-cast MAC to port mapping and associated connection WO94/07316 2 1 4 ~ 1 5 ~ PCT/US93/08674 35 ~ ;
are used. The MAC SDU is encapsulated in an 802.6 frame and passed to the AA~ 4 function with the MID
associated with this ATM MAC entity for transmission of that multicast connection.
All the above took place on Lyra. The subsequent steps take place on Altera as it receives the ATM ARP
and the ATM MAC PDU cont~n;ng user data.

o The ATM ARP is received by all MAC entities including Altera. The other MACs determine that the requested MAC address is not theirs and ignore the request. Altera determines that its MAC address i9 in the request. Altera updates its MAC to port address table with Lyra's MAC and port addresses provided in the ATM ARP request. Next an ATM ARP reply is con-structed using Altera's port and MAC addresses. This request, in the form of an MAC SDU with Lyra's MAC
address as the destination, is passed to the ATM MAC
entity.
o The ATM MAC looks up Lyra~s MAC address in the M~C to port address table. It finds Lyra's port address. The port to VCI table is searched using that port address. No entry is found. Connection manage-ment is invoked to establish a connection to Lyra.
Connection management passes a SETUP request to ATM
signaling. The MAC queues the ATM ARP response until the connection is established.

o Altera ATM signaling module sends a SETUP PDU to establish a connection to port address dl:41:57:80:-77:68:00:02. The upper layer protocol (sometimes called upper layer compatibility) is the ATM LAN MAC.
(This is not a function of the ATM MAC. But it is included for illustrative purposes.) o Next all stations receive the MAC SDU cont~;n;ng 21441~ ---3~-the user data on the broadcast connection. All sta-tions except Altera detPrm;ne that the destination MAC address is not theirs and drop the frame. Altera accepts the frame strips off the 802.6 and LLC/SNAP
overhead and passes the frame up to the user function identified by LLC/SNAP.
At this time, the SDU provided to Lyra's ATM MAC
has been delivered to the appropriate MAC user on Altera. However, the MAC entities continue connec-tion establishment and address resolution for subse-quent commlln;cations between the two stations. The next sequence of operations occurs on Lyra.

o ATM signaling on Lyra receives a connection setup indication from the network. This indication is passed up to the upper layer protocol which in this instance is the ATM MAC.

o The ATM MAC receives a setup indication SDU from signaling. At this point Lyra knows some other station's ATM MAC is trying to setup a connection to it. The port to vci table is searched for a connec-tion to the callers port address. In this case none is found. The connection is accepted by passing a CONNECT SDU to ATM signaling. The MAC starts an idle timer for the connection. Note, that the ATM MAC can not use this connection until an AT~ ARP request or response is received indicating MAC addresses for stations accessible via the connection.
o Lyra's ATM signaling transmits a CONNECT PDU to the network. Typically, network commlln;cation is bi-directional. Assuming this is the case the MfAC
service user on Altera has responded to the MAC SDU
indication with a MAC SDU request. The following actions take place on Altera. The ordering of the arrival of MAC SDU and the CONNECT SDU are arbitrary.

WO94/07316 2 1 4 ~ ~ 5 ~ PCT/US93/08674 ~37~
o The MAC service user passed the ATM MAC an SDU
with a destination MAC address of 00:80:b2:eO:00:50 (Lyra's). The MAC finds the mapping from MAC address to port address learned when the ATM ARP request was received from Lyra. The MAC next finds that it is setting up a connection to Lyra's port address and that the connection is not yet established. A MAC PDU
is created from the MAC SDU and queued waiting connection establishment.
o Altera ATM signaling receives a connect PDU. This is passed up to the MAC as a SETUP confirmation. The ATM signaling sends a CONNECT acknowledge PDU to Lyra. The connection is considered established.
o Altera~s ATM MAC, upon receiving the SETUP
confirmation, transmits all frames which were queued awaiting connection establishment. The ATM ARP reply is the first frame to transmitted. It is followed by the MAC PDU cont~;n;ng user data.
At this TIME, address resolution and connection are complete on Altera. Any further frames addressed to Lyra's MAC address will use the new connection.
The connection is not established on Lyra. Also Lyra still does not have a mapping for Altera's MAC
address. The following actions complete address resolution and connection establishment on Altera.

o The ATM ARP reply is received on the connection which is still being setup. (Note most ATM networks r have slower signaling ch~nnels than payload channels.
Typically the ATM ARP response will be received prior r to the CONNECT acknowledge PDU.) o The MAC enters Lyra's MAC address to port address mapping in the MAC to port table. At this point any MAC UNIT-DATA requests will be queued until W O 94/07316 PC~r/US93/08674 ~ 38-the SETUP complete indication for the connection is passed up from ATM signaling.

o The MAC PDU cont~;n;ng user data from Lyra`s MAC
users is received. The 802.6, LLC and SNAP headers are removed and a MAC UNITDATA indication is passed up to the appropriate MAC service user.

o Altera's ATM signaling receives a CONNECT_ACK
PDU. This moves the connection into established state. The ATM signaling function passes up a SETUP
COMPLETE indication informing the ATM MAC it may transmit on the connection. Connection management starts its idle timer for the connection.
The connection is now established on both sta-tions. One or more MAC UNITDATA SDUs have been deliv-ered. The connection will be timed out as per local policy decisions.

ATM LAN Code Overview One detailed embodiment of computer software code used in connection with the present invention appears in the VIRTUAL NETWORK USING ASYNCHRONOUS TRANSFER
MODE APPENDIX.
The ATM LAN MAC code in the appendix is organized by functional components and Operating System (OS) dependencies. The file if_atm.c contains the rou-tines which contain OS dep~n~ncies and which are typically implemented differently for each OS. The unicast unit 25 and multicast unit 24 address resolu-tion functions are implemented in the file atmarp.c.
The file atmarp.h contains the definitions for the ATM ARP protocol and the structures u~ed by atmarp.c to implement the protocol. The file atm.c implements the function of connection management unit 27. Those routines interact with the ATM signaling function to establish and release connections. The framing unit W094/07316 2 1 4 ~ 1 5 I PCT/US93/08674 ., . i ~ .
- .3~ - . i ., 26 function is implemented in the OS specific file if_niu.c in the routines niuoutput(), atm_mac_input() which encapsulate and decapsulate frames respective-r ly~ The station management unit 28 functions are implm~nPnted in atm_init.c and in parts of the ATM
signaling unit 28 in the files svc.c, svc_utl.c and svc_pdu.c. The ATM ~AN server unit i2 functions are implemented in the files lm.c, lm_cfg.c, lm_mgmt.c and lm_util.c.
In the APPENDIX the configuration management units 20 and 40 are implemented in an alternate embodiment wherein the operational unit 28 PDUS
rather than in a switched VCs as previously describe-d.
While the invention has been particularly shown and described with reference to preferred embodiments thereof it will be understood by those skilled in the art that various changes in form and details may be made therein without departing from the spirit and scope of the invention.

W O 94/07316 P~r/US93/08674 21~15ll ~o atm.c atm.c * COPYRIGHT 1992 ADAi TlVE CORPORATION
* Ai L RIGHTS RESERVED
*/
* This file contains: atm initO is cailed at initiaikation.
* atm find atpO returns an atmH ghen a MiAC and physicai i/f.
* atm flnt macO retums an atmK given a MiAC. atm sdu handlerO Is * the ~l~el~ace to ATM signaiing. atm releaseO releases a VC and * frees any queued packets. atm find atO sea - hes for an arptab * entry given a mac address. atm Initrate setupO Initiates VC
* ~ Id.
*/
static char sccsidl] = ~%A%~;
#include ~atm.hU
#include ~svc.h #include ~debug.h #include ~niu.h~
#Include atmarp.h #include ~llc.h #Include~K atm.h~
int atm trace = 2;
#define TL1 #define TL2 atm trace> 1 #define TL3 atm trace>2 #defineTL4 atm trace>3 #deflne TL5 atm trace>4 Int atm assert panic= 1;
#define HASHMA(x) HASH LOW((x)->aa long[11) /* pass in a atm addr */
#define HASH LOW(partO)~((partO~ >8)~partO))&Oxf) /* pass in low 32 bits * of addr~/
/*
* atm initO is called to allocate atm glob which contalns ail the * ATi i LAN MAC global var~ables wh~ch are written after p uyl~rll load.
*/
atm initO
{
int i atm mac inputO atm sdu handlerO;
struct atm globs *ag = atm glob;
K (ag->atm initialked) WO 94/07316 2 1 4 ~ 1 5 ~ PCI/US93/08674 .

~/
atm.c return O;
ag->atmifn 5 NNIU * NATMS;
ag->atm ulp = ulp l~y;st~l(LNI MAC ORG, LA/il MAC PID, atrr mac Input, atm sdu handler, O);
"u short *` & ag->llc def 0 = Oxaaaa;
u short * & ag->llc def 1 = Ox0300;
u short * & ag->llc def 2 = OxO;
,u short *, & ag->llc def, 3 = OxO;
ag->atm null-aa iongrO] = O;
ag->atm null.aa long[1] = 0;
ag->atm null.aa type = MT NULL;
ag->atm br~lcs~t ~ long[O~ = O;
ag->atm b. ~-lr~ long[1 ] = 0;
ag->atrn b,~rlc~ type = MT MAC;
for (i = O, i < 6; i++) ~
ag->atm br~dc~ byte[ATM FIRST MAC + i] =
(u cha~ Oxff;
ag->atm initialized= 1;
return;

/
* atm find atpO retums an ATM LAN structure pointer, atp, given a * por~ address and a phys l/f.
struct atmH *
atm find atp(pc, port) struct pcif *pc;
{ struct atm_addr port;
struct atmif *atp;
for (atp = pc->pc atmif; atp; atp = atp->ati next) if (ATM ADDR I~Q(atp->ati port, *port)) return atp;
return (struct atmH *) O;
}

/*
* atm_fint atO retums a pointer to an atm ;,lte,r~ce entry to be * used for a specific MAC address.
*/
struct atmif *
atm find mac(mac) u char *mac;
struct atm addr addr;
struct pcif~ *pc;
struct atmif *atp;

W O 94/07316 PC~r/US93/08674 .

atm.c atm bzero(&addr, sizeof(addr));
atrn bcopy(mac, 8addr.aa byte[2], 6);
addr.aa type = MT MAC, for (pc = svc glob-~svc pcif; pc < svc glob->svc pcifn; pc++) for (atp = pc-~pc atrnH; atp; atp = atp-~ati n~
if (ATM ADDR EQ(atp->ati mac, addr)) retum atp;
return 0;

* atm sdu handlerO handles s~gnaling SDUs from the ATM signaling * module. The necessary ATM ARP routines are called at conne~ion * e~L~Ll:she",enl and release.
*/
atm sdu h~lldldr(.~p, sdu, len) struct vcte *vp;
struct setup *sdu int len;
struct ulptab *ulp;
int rtn-struct vcte *ovp; /* other VC */
ASSERT(VALID VP(vp));
TRl(TL~,~atm sdu handler(%s)\nU, svc xdu type str(sdu->lmi pdu type));
H (vp->vcte flags & VCTEF MCAST SERVER) {
if (ulp = u~p find(LMI MCAST PID, LMI MCAST ORG)) {
ASSERT(~ALID ULP(vp->vcte ulp));
ulp free(vp->vcte ulp);
ulp~tax(ulp);
vp->vcte ulp = ulp;
(*ulp->ulp Imi) (vp, sdu, len);
} else atm release(vp, INVAUD DST ADDR);
return;
switch (sdu->lmi pdu type) {
case SDU SETUF IND:
if (Isvc ~nd loca~ port(vp->vcte pcif, &((struct setup *) sdu)->lmi callee)) {
atm release(vp, INVALID DST ADDR);
breal~;
ASSERT(vp->vcte atmif == 0);
vp->vcte atmif = atm find atp(vp->vcte pcif, ~ &vp->vcte~oca7~;
ASSERT(VALID ATP(vp->vcte atm-O;

WO 94/07316 2 1 ~ 4 1 5 ~ PCT~/US93/08674 ~ 3 , j .~ ji . ~
atm.c ovp = svc_find vc(vp->vcte pcH, &vp-~vcte iocai, &vp->vcte peer, atm glob->atm ulp, VCS NOT i~EAD OR DYING & ~T1 << VCS WSR));
H (ovp && bcmp(&vp-~vcte locai, vp-~vcte peer, skeof(struct atm addr))) {
H (atm incoming vc is better(vp, ovp)) {
arp release(ovp->vcte atmH->ati arptab, ovp);
atm release(ovp, VC REDUNDAI~;
} else {
atm free msi(sri~
atm release(vp, VC REDUNDANT);
break;
}
sdu->lmi pdu type = SDU SETUP RESP;
H (rtn = svc sdu(vp->vcte pcH, vp, sdu, sizeofTstruct setup))) TR1(Ti, hsvc sdu(SETUP RESP)->%d\n4, rtn);
break;
case SDU SETUP COMP:
if (bcmp~&vp->vcte local, vp->vcte peer, sizeof(struct atm addr))) arp setup(vp->vcte atmH->ati arptab, vp);
case SDIJ SETUP CONF:
atm free msg(sdu);
if (vp->vcte packet) atm send packets(vp);
break;
case SDU RELEASE IND:
if (vp->vcte packe~
atm free i~"ets(vp);
arp reTease(vp->vcte atmif->ati arptab, vp);
atrn free ms~(sdu);
break;
case SDU STATUS RESP:
atm free msg(sdu);
break;
default:
panlc(Uunknown sdu");
break;
}
/*
* atm incoming vc is betterO choses the better VC given two * redundant VCs. V~e i~mit the number for VCs to one i~ An every * pair of ports. When a new VC is initlated we check for a * dnp'ic~tss The VC initiated by the statlon with the lowest port * address is released. It is i"",~,dLI~/e that both sides use this * `~rrLI"" uLhe~ ; e we could end up In a deadly er"i,ldce.

W O 94/07316 PC~r/US93/08674 .

2 ~ 4 ~ 4 atm.c */
atm incoming vc is better(ivp, ovp) struct vcte *ivp; /* incoming VC ~/
struct vcte *ovp; /* olt~r` .g VC ~we Initiated) */
struct atm addr *ours, *theirs;
int ~ tnue;
ASSERT(ovp l= ivp);
TR2(Ti~, ~atm sdu handler dup vcs found %x & %x\n~, ivp, ovp);
H (ivp-~vcte p-cH->pc fiags & PCIF NIU TO NIU) {
/* COm~lt~ MAC add,t,~ses */
true = ivp->vcte pCH-~pc fiags & PCIF OTHER NiAC ADDR iS HIGHER;
} else { /* co,-"~ar~ port adci,t:~ses */
true = ATM ADDR GT(ivp->vcte peer, ivp->vcte iocai);
TR2(Ti~, "atm incoming vc is%s better(96s) \n~, true ~ " not", e160 ntoa(&ivp->vcte peer));
ASSERT(ovp), /* keep ovp alive */
return true;
}

* atm releaseO sends a release req to the svc module and frees any * queued packets.
*/
atm release(vp, cause) struct vcte *vp;
struct release *rdu;
Int rtn;
H (vp->vcte packet) atm free pack~(vp);
H (!(rdu = (struct release *) atm alloc msgO)) {
plillli('~lll release: no memory~); ~
retum;
rdu->lml proto= iJ\fil PROTOCOL;
rdu->lmi pdu type = SDU REi EASE REQ;
rdu->lmi~cref~type = vp->vcte cref type;
rdu->lmi~cref~vaiue = vp->vcte cre~ value;
LMI SET Fl ~-~JT(&rdu->lml cause, LMI RELEASE CAUSE, cause);
H (rtn = svc sdu(vp->vcte pcH,vp,~du,~k~of(Ar~u))) TR1 (TL1, ~atm release: release failed %d\n~, rtn);

W O 94/07316 ~ 5 4 PC~r/US93/08674 .

atm.c * atm find atO sea,cl,es for an arptab entry given a rnac address.
* The bes~ entry upon which to send to the mac address is * returned. If the entry has no VC this routins ~lt,n",t~ to setup * ons.
u char atm l"aci,,uA~'r~ [6] = {Oxff, O~f, O~f, O~f, O~df, O~f};
struct aate *
atm find at(atp, dst) struct atmH *atp;
u char *dst;
{

struct vcte *vp = O;
struct aate *at;
ASSERT(VAi~D ATP(atp)3;
at = atm mac to ~te(~tr dst);
if (lat) 7* wB-qu-eue frames now~
* lat->aate vcte) */
at = atm mac to_~tP(~tr. atm ",aci ~ r~ dO;
if (lat) retum O;
H (!at->aate vcte) atm initiate setùp(atp at);
return at;

/*
* atm initiate setupO initiates a vc setup between to the port * add,e~ses using the specHic i"lt ,~ace. If there is already a vc * coming up between the two ports using that ill~ dCe we do not * bother. This huarantees that we do not Initiate two VCs to the * same port address. When we get setup indications we must aiso * check for d nr'icAtPS and decide which VC to keep.
*/
atm initiate setur(~tr, at) struct atrnH *atp;
struct aate *at;
int rtn;
struct pcH *pc = atp->ati pcH;
struct atm addr *from = &atp->ati port;
struct vcte *vp;
struct setup *pdu; /* setup pdu and sciu are the same */
struct Imi ulp *lu;
H (pc-~pc s~g->vcte state != VCS ACTIVE) W0 94/07316 Pcr/US93/08674 2 ~ 4 ~
atm.c /* no signaiing yet */
retum O;
vp z svc find vc(pc, from, &at->aate dt..~d i~, atm glol~ >atm ulp, VCS NOT=DEAD OR DYiNG);
goto found a vc;
_ _ pdu = (struct setup *) atm ailoc msgO;
H (Ipdu) retum 0;
pdu->lmi proto= LMI PROTOCOi_ pdu-~lm ncalls= 1;
pdu->lm caller= *from;
pdu->lm callee = at->aate ~--,addl, pdu->lm pdu type = SDU-SETUP REQ;
pciu->lmi cref type= LMI CREFT~E SVC;
pdu->lmi cref~vaiue 5 0;~* let svc module pick one */
lu = (struct ImT ulp *) & pdu11];
lu->af type = Chll UU;
lu->af aal = PAYL~)AD ML 4;
lu->af pid = Livil MAC PID;
lu->af org = LMii MAC ORG;
if (rtn = svc sdu(pc, 0, pdu, skeof(*pdu) + skeof(*lu))) TR1(TL2, iratm initiate setup: svc_sdu->%d\n~, rtn);
vp = svc find vc(pc, from, &at->aate all..addl, atm glob->atm ulp, VCS NOT Di--AD OR DYING);
found a vc:
if (vp) {
at->aate vcte = vp;
vp->vcte atmif = atp;
svc inc(vp);
TR1 (TL1, ~atm find at: setup to 96s failed\n~, e160 ntoa~&at->aate ~t...add~));
}

WO 94/07316 2 1 4~ PCI/US93/08674 atm.h /* atm.h * COPYRIGHT 1992 ADAPTIVE CORPORATION
* Ail RIGHTS RESERVED
/
#Hndef NIU ATM H
#define NIU ATM i-i induded #include ~bytes.h~
#include ~unipdu.h~
/*
* atm mac service l"le, tdce (asl). Th~s is the same as an ethemet * header so that upper layers can simply assume ATM is an ethemet.
*/
struct atmmsi {
u char asl dst[6];
u char asi src[6];
u short asi type;
};
/*
* Structure of an ATM mac header for aal type 4, this is an 802.6 * header.
*/
struct atm header {
struct atm addr atm dst;
struct atm addr atm src;
union {
struct {
u int mcb pid:6;
u int mcb pad:2;
u int mcb delay:3;
u int mcb ioss:1;
u int mcb crc:1;
u int mcb elen:3;
u int mcb pad1:16;
} mcbits;
u int atm mcb ion~i;
} un mcb;
};
#define atm mcbits un mcb.atm mcb long #define atrn elen un mcb.mcbits.mcb elen #define atrn crc un rncb.mcbits.mcb crc - #define atm loss un mcb.mcbits.mcb loss #define atm delay un mcb.mcbits.mcb delay #define atm pid un mcb.mcbits.mcb pid WO 94/07316 PCI`/US93/08674 2 1 4 ~
- atm.h #define ATM PID iLLC 1 /* protocol ID for LLC */
7~define ATi~ MCBITS NOCRC 0x04000000 /* protocol id 1 */
#define ATM-HDR LE~i skeof(struct atm header) #define ATM PAD SHIFT 24 /*
* The only header ~Atlt:nslon defineci Is a retum port address. The * length must be set to ATME RPA SIZE. Pad exists to get the 64 bit * address 64 bit aiigned relative to the atm header.
*/
struct atm header ext {
u char atme ien;
u char atme type;
u char atme~pad[2]; /* need not be zeros (nnbz) */
struct atm addr atrne rpa; /* retum port address */

#define ATME RPA TYPE 112 /* out of SMDS range */
#define ATME -RPA -BYTES sizeof(struct atm header ext) #define ATMi--RPA-WORDS ((skeof(struct atm header ext) +3)/4) /*
* Callers to atm data reqO must ensure atieast ATM DATA REQ ROOM
* bytes are avairable ~n front of the packet data.
*/
~define ATM DATA REQ ROOM (ATM i-iDR LEN+LLC SNAP LEN+ATME RPA BYrES) /*
* multicast address structures are linked to atm arptabs which are * markeci ATF MULTI. Such entries are not t~med out, nor are they * freed when underiying VCs are .~l~ased. atm delete lanO free's * the ATF MULTI atm arptab entries and atm add lan~ &
* atm niu~to niu0 ro~"~ e them and re initiate MC VCs for the *j~y;~ ~d ad i,dsses.
struct mcaddr ~
u char mc ~n~WI [6]; /* rnl ~ltic~ct address */
u short mc count; /* t~fert:nce count */
structaate *mc at; /* multicastVC */
};
#define MCADDRiVlAX 64 /* multicast addr table length */
#define MCCOUNTW~X (32*102~1) t* multicast addr max * .~fer~nce count */
* atmif, one per atm lan, useci by atm lan layer struct atmif ~

W O 94/07316 2 ~ PC~r/US93/08674 , :
~9 atm.h struct niu arpcom *ati ac; /* contains arp and ifnet * structures ~/
struct atmif *ati next; /* linked off pcif structure */
u short ati state; /* basicaily do we know who * we are */
u short ati mid;/* mid used for muiticast frames */
u short ati rncasts; /* max # multicasts circuits * configured */
struct atm addr ati port;
struct atm addr ati mac;
#define ac mac ati mac.aa byte[2 struct pcif *ati pcif;
struct aate *at~ arptab; /* set at initialization */
Int ati num mcasts;
struct mcaddr ati mcaddrs[MCADDRMAX];
};
/* ati state */
#define ATS INACTIVE O
~define ATS ACTIVE 3 -/*
* global data structure for r/w variables and variables explicitiy * initialkeci.
*/
#include "llc.h~
struct atm globs {
struct H tr hdr *Itrb-struct atm7~ *atmif, int atmifn;
int atmif used;
struct llc snap llc def struct atm addr atm i~nJAr struct atm addr atrn null;
struct ulptab *atm ulp;
Int atm InEiaiked;
char static bufl32];
};
~ifndef RT68K
extern struct atm globs atm globs;
#define atm glob (&atm globs) #else #define atm glob atm get giobO
struct atm globs *atm get globO;
#endif W O 94/07316 P~r/US93/08674 2 1 ~
atm2 h #define LEN FOR MBUF PTRS nxf~560007 #define HASH NiULTlCAST ADDRESS(x) ((x)&Oxfl~
caddr t atm alloc ms~O, atm ailoc bytesO;
#define NATMS ~4 /~rnax # of A-TM lans per physicai * I,l~.tacc ~/
#define el60 ntoa svc el64 ntoa/* these are reaily E.164 ad.l,~sses */
#endlf /* NIU ATM H ~/

WO 94/07316 - ~5,/ 2 1 4 4 1 ~ ~ PCr/US93/08674 atm Init.c /* aUn init.c * COPYRIGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERV~D
* This file contains the ATM IAN co, ' ~ rr~tion routines. They are * called by the ATM ~Iyl " Ig module when slgnaling enters the * ACTIVE state and one or more ATM lANs have been provisloned * added by NM and they are c~led when sl~ allislliu~ to * the WGRC state to deleted~ the ATM lANs.
~ atm_attach lanO r~ t~s atmlf stnuctures and Inltiaikes thern * atm add lanO actives an ATM LAN initiates. atm_delete lanO
* deactiuates an ATM IAN. atm niu to niuO activates an ATNi IAN in * back to back configuration. atm trace_bufO add a trace record to * the trace buffer. atm trace strO add a strins~ to the trace * buffer.
*/
static char sccsid~3 = %A%;
#include ~debug. h #include niu.h iYinclude atm.h #include "atmarp. h ;~include "svc.h~
#include "debug.h ~include trace.h ~inciudeff atm.h"
#define TLI
#define TL2 atm trace> 1 #defineTL3 atm trace>2 #define TL4 atm trace>3 #defineTL5 atm trace>4 extern int atm trace;
/*
* atm attach lanO Is called when the maximum number of ATM LANs for * a particular plysical interface is known. The app~uprhle number * of atm lan interface stnuctures are "~ and linked into the * physical interface structure.
/
atm attach_lan(atp, pc) slruct atmif *atp;
struct pcif *pc;
{

struct atmif *an;

W O 94/07316 PC~r/US93/08674 2~4~5~
atm init.c if (an = pc->pc atmii~ {
while (an->atrn~) an = an->ati next;
an->ati ne3~t = atp;
atp-~atr next = 0;
} else {
atp-~ati next = 0;
pc-~pc_atmif = atp;
atp-~ati pcif = pc;
ASSERT(atp->ati state == ATS iNACTlVE);
if set mac(atp);
atm arptab ~ tp);
atrn bzero~tp->ati "Icad i~ keut(~t~>ati r"cad il;,));
atp->atl num mcasts= 1;
atp->atr",cadd~[o].mc count= 1;
atm bcopy(&atm glob-~atm i~IOR~ICa!~1 RR byte[ATM FIRST MAC], atp->ati ",cadd.~[O].mc enaddr, 6);
if (pc->pc frags & PCli~ NI~TO NIU) atm niu to niu(atp);
}

/*
* This is called when a real switch tells use some real port * addlesses. The mte's were freed when the previous lan was * deleted. If the mtu is zero this ~s a null LAN. It should not be * made active. This allows users to configure l,~ ces starting * at aa2, aa3, etc.
*/
atm add lan(atp, port, mid, mcasts, mtu) struct atmif *atp;
struct atm addr *port;
TR1(1L1, ~atm add lan: port = 96s~, e160 ntoa~/~atp->ati port));
if (mtu == 0) retum;
atp->ati state = ATS ACTIVE;
atp->ati mid = mid;
atp-~ati mcasts= mcasts;
atp-~ati~port = *port;
if add ian(atp, mtu);
atm setup u.rs~ (R~
TR1~L2, ~atm add lan: port = %s~, e160 ntoa(~atp-~ati port));
TR1 (TL2, ~ mac = 9~s\n~, e160 ntoa(&atp->ati mac));

W O 94/07316 2 1 4 ~ PC~r/US93/08674 ~3 ~ .
atm init.c atm setup ~
struct atmff *atp;
int j;
struct mcaddr *mc;
for (i = 0; i ~ atp-~ati num mcasts; i+ +) {
mc = &atp->ati Illcadd~ i];
ASSERT(mc-~mc at == 0);
mc->mc at = atm find at(atp, mc->mc enaddr);
ASSERT~mc->mc at);
mc->mc at->aate flags l= ATF MULTI;
TR1(TL3, "atm setup mcast: port = %s\n~, e160 ntoa~mc->mc at->aate ~ addl));

/*
* Called to free up any resources tied up by the ATM LAN, atp. The * arptab has been cleared by release indi~lions except for * ATF MUUI entries. Here we go through list of ,t~ red * mult~cast addl~sses free those arptab entries l~terllced.
*/
atm delete ian(atp) struct atmif *atp;
struct mcaddr *mc;
atp->ati state = ATS INACTIVE;
TR1(TL1, ~atm delete~an: port = %sU, e160 ntoa~atp->ati port));
TR1(TL1, ~ mac = %s\n", e160 ntoa(&atp->ati mac));
atp->ati port.aa type = MT NULL;
for (mc - atp-~ati ",cadd~
mc < &atp->ati Illca i il~[atp->ati num mcasts]; mc+ +) {
ASSERT(mc->mc count);
ff (mc->mc at) { ~
ASSERT~mc->mc at->aate fiags & ATF MULTI);
mc->mc at->aate fiags = 0;
atm aate free(mc->mc at);
} mc->mc_at = o;

} if_delete_ian(atp);

* set a local port address and mac address based upon mac address in * niu arpcom retelt:nced by atp. This is used when changing atm lan * configuratlon to a niu-to-niu configuration. Aiso set to ..

W O 94/07316 PC~r/US93/08674 .

~1441~4 atm init.c * broadca~ mte entry and K signaling not dehuDged instail a nailed * up bloadc~sL vc.
*/ ., atm niu to niu(atp) struct atmK *atp;
extem int gosig, niumtu;
atm bzero(&atp-~at~ port, s,~eor(a~,u->ati port));
atp->atT port.aa type 5 MT PORT;
atm bcopy(&atp >ati mac.aa byte[ATM FIRST iYiAc]~
&atp->ati port.aa byte[ATM N2N MAC], 6), atp->ati port.aa lannum = K get lanratp);
atp->ati state - ATS ACTIVE;
atp->ati mcasts = 32; /* its arbitrary */
atp->atl mid = O; /* must be zero till Ai AN aal driver * gets fixed */
K add lan(atp, O); /* do not change mtu */
atm setup rn~ t~ tr);
- TR1~ri 2, ~atm niu to niu: port = %s~, e160 ntoa~atp->ati port)) TR1(Ti2, ~ mac = %s\riii, e160 ntoa(&atp->ati mac));
}
svc trace pdu(p, len, in, vci) char ~ *p;
atm trace buf(p, atm bcopy, SVC PDU TRACE, len, in, vci);

* atm trace bufO add a trace record to the trace buifer.
int atm trace iimit = 64;
atm trace buf(p, copyproc, sub, tien, in, vci) caddr t p;
int ~ (*copyproc) O;
struct K tr hdr *rb;
int ~ ~ s, len;
K (tlen > atm trace limit) len = atm trace 11mit;
else len = tien;
rb = (struct K tr hdr *) tr get entry(skeof *rb + len);
atm glob->ltrb = rb;
if (~rb) W O 94/07316 2 1 ~ 4 PC~r/US93/08674 atm_init.c ~, .
retum;
rb-~thdr.subsystem = sub;
rb->thdr.sss = In;
rb->thdr.length = len;
ri~>tien = tien;
atm settime(rb->thdr.tlme);
rb-~vci = vcl;
(*copyproc) (p, (char *) &rb[1], len);

/*
* atm trace strO add a string to the trace buffer.
atm_trace str(str) char *str;
{

struct trace header *tr;
int 7en;
for (len = O; str[len]; len+ +);
tr = (struct trace header *) tr get entry(sizeof *tr + len);
if (Itr) return;
tr->subsystem = ASCII LOG;
tr->sss = O;
tr->length = len;
atm settime(tr->time);
atm bcopy((u char *) str, (u char *) & tr[1], len);

WO 94/07316 ` ` PCI/US93/08674 2 1 ~
atmarp.c /* atmarp.c * COPYRlGi-iT 1992 ADAPTIVE CORPORATION
* ALi RlGi-iTS RESERVED
*
* ATM addrsss ,, ~lni~ln protocol. This module contains the routines * whlch Implement atm arp. The two primary entry polnts are * atm mac to aateO and atm arp inputO.
* atm mac to aateO retums a pointer to and atm arp table entry.
* atm~arp ~nputO handles ail atm arp requests and replles.
/

static char sccsld[l = ~%A96~;
~ifdef notdef #include ~ail.h~
#include"ip errs.h~
#include ~unsp.hU
#endH /* notdef */
#include ~atm.h~
#include "svc.h~
#inciude ~atmarp.h"
#include "debug.h~
#include~H atm.h~
#define TL1 #defineTL2 arp trace>1 #define TL3 arp trace>2 #define TL4 arp trace>3 #define TL5 arp trace>4 int arp trace = 2;
Int arp debug = 2;
char *atm mac sprinffO;
#define N MTE S 64 struct aate~ atrn aate[N MTE S * ATM ARP TABi FS];
Int atm aate size = N -MTE S *-ATM ARP TABLES;
int atm arptabs = O;/* number of tables ailocated (1 per * atm ran) */

struct aate *
atm arptab look(~tp, addr) struct atmH *atp;
u char *addr;
struct aate *ate = atp->ati arptab, *end;

WO 94/07316 2 1 4 a~ PCr/US93/08674
5?
atmarp.c end = 8ate[N MTE S];
whlle (ate ~ end) {
if (atm i~c",p(ale->aate "~cad il, addr, ~ keof(ald-~aate "~acad i~ O) return ate;
else ate+ +;
}

retum O;

* Broadcast an ATM ARP packet, asking who has addr on atm lan ac.
atm arprequest(atp, addr) struct atmif *atp;
u char *addr;
{

struct atm arp *aa;
TR2(Ti~, "atm arprequest(96x, 96s)\n~, atp, atm mac sprintf(addr, 6));
aa = (struct atm arp *) atm alloc msgO;
if (~aa) retum;
aa->aa llp= htons(ARPHRD ATM);
aa-~aa ulp = htons(ETHERT~PE ATMiviAC);
aa-~aa llp len = skeof(aa->aa sender port);
aa-~aa ulp len = slzeof(aa-~aa sender mac);
aa-~aa msg type = htons(ATM ARP Ri~QUEST);
atm bcopy((caddr t) & atp->ati~port,~(caddr t) aa->aa sender port, TU int) sizeof(aa-~aa sender port));
atm bcopy((caddr t) & atp->ac mac, (caddr t) aa->aa sender mac, TU int) skeof(aa-~aa sender mac));
atm bcopy((caddr t) addr, (caddr t) aa-~aa target mac, TU int) sizeof(aa-~aa target mac));
atm bzero((caddr t) aa-~aa target port, skeof(aa-~aa tar~et port));
atm send arp(atp, addr, aa, skeof~aa));

/*
* atm mac to aateO retums a pointer to and atm arp table entry.
* desten Is filled in. If there Is no entry in arptab, set one up and * broadcast a request for the MiAC address. An arptab point is * retumed if an exlsting arptab entry was found. for the mac * address is found (or computed).
*/
r W O 94/07316 - PC~r/US93/08674 2 ~ 5 ~1 ~
g~
atmarp.c struct aate *
atm mac to aate(ac, destmac) struct atm7~ *ac;
u char *destmac;
{
struct aate ~at;
TR2(TL4, ~atm mac to aate(%x, %s)\n~, ac, atm mac sprintfTdestmac, 6));
at = atm arptab look(ac, destmac);
if (at = = 0) { 7* not found *t at ~ atm aate ailoc(ac->ati arptab, de~ ,~c);
H (at =e 0) panic(~atm mac to aate no free entry~);
if (latm bcmp(destmac, 8ac->ac mac, 6)) {
atm bcopy('caddr t) & ac->ati port, ~caddr t & at->aate ~1"ad i"
(u i~it) s ~t vt(ac-~atrport));
atm bcopy((caddr t) & ac->ac mac, Tcaddr t) at-~aate ",acadd"
(u int) sizeof(at->aate macaddr));
at->aate timer= 0;
at->aate fia3s = MTF COMPLETE;
at->aate vcte = o;
TR2(TL4, ~ -> 96x %s\n~, at, svc el64 ntoa(&at->aate ~I "acl i,));
retum at;
} else if (destmac[0] & 0xl) {
/*
* Caiulate a suitable atm address to make a * connection with for this multicast * address */
all 1 ,~r~." ,hasl~(ac, destmac, (caddr t) & at->aate ~",add,);
atm bcopy~ie~."ac, (caddr t) at->aate "
~ u int) skeof(at->aate, rA-I I )); ~
at->aate timer= 0;
at->aate flags = MTF COMPLETE;
at->aate~vcte = 0; /* no vcte get */
TR2(TL4, ~ -> %x %s\n~, at, svc el64 ntoa(&at->aate ~",ad i~));
retum at;
}

/*
* Cener~le an ARP request, MTF RESOLVING avoids recurslon at->aate flags l= MTF RESOLVING;
atm arprequest(~r, dectm~r);
6 2 1 4 ~ 1 5 ~ PCI`/US93/08674 atmarp.c at->aate flags &= ~MTF RESOLVING;
TR0trL4,~-> 0\n~);
} retum 0;
at->aate timer = o; /* restart the timer */
if (at->aate fla~s & MTF COMPLETE) { /* entry IS co~ Jlut~ */
TR2(TL4,~-> %x%s\n'rat, svc el64 ntoa(8at->aate ~l~ad ll));
retum at;

* There is an aate entry, but no e164 address ~spol1se yet.
* Avoid Inflnite recursion by using the MTF RESOLVING flag.
* This is temporary. The port to rt68k will neces~ 'e * restructuring which, hopefully, will remove the need for * this flag.
if (I(at->aate flags & MTF RESOLVING)) {
at->aate flags l= MTF RESOLVING;
atm arpre~iuest(~, des~"lac);
- at-~ aate flags & = ~MTF RESOLVING;
TR0(TL4,"-> 0\n~);
return 0;

/*
* atm arp inputO handles all atm arp reguests and replles.
atm arp input(atp, aa, src) struct atmif *atp;
struct atm arp *aa;
u char ~ *src;
struct aate *at;
u char target mac[6]; /* copy of target protocol * address */
struct atm addr *sport;
TR2(TL2, ~atm arp input(from 96s / %s)\n~, atm mac sp,i,l~7(aa->aa sender mac, 6), svc e164 ntoa(aa->aa sender port));
if (aa->aa ulp i= i-THERTYPE ATMiMAC) goto drop;
/* make a copy of target mac for use later */
atm bcopy((caddr t) aa->aa target mac, (caddr t) target mac, ~_int) skeor(~r~et mac)~;
if (!atm bcmp((caddr t) aa->aa sender mac, (caddr t) & atp->ac mac, 2 3L 4 d~ 15 l~ G
atmarp.c c,r(aa->aa sender mac))) /* its from me so rust drop It */
goto drop;
/*
* Search the local d~ cc for senders mac address. Update * the ~ ~se wlth new In~u,..~lion (first deleting old * Infomatlon).
*/
at = atm arptab '~s'~tp aa->aa sender mac);
H (at) { /* If at is coi-, ' and address Is * dfflerent then free entry */
H (at->aate flags & MTF COMPLETE) {
if (atm bcmp(aa->aa sender port, (caddr t) & at->aate atmaddr, (u int~skeof(aa->aa sender port)) I= o~{ /* if different */
atm aate free(at);
at - 0;
} else { /* if at is i,,cu,, ' ~ update it */
atm bcopy((caddr t) aa->aa sender port, (caddr t) & at->aate ~,.,ad.l"
skeof(aa->aa sender port));
- at->aate flags 1- MTF ~OMPi FTE;

/*
* If we did'nt find his mac address and he IS looking for * us. Then learn his as well */
if (at == 0 && latm bcmp(target mac, &atp->ac mac, ~keor(~ry~t mac))) {
/* ensure we have a table entry */
H (at = atm aate ~ " c(~tp->ati arptab, aa->aa sender mac)) {
atm bcopy((caddr t) aa->aa~sender port, (caddr t) -& at->aate ~ ,addr, (u Int) ~ or(aa->aa sender port)~;
at->aate flags l= MTi- CoMFi FTE;

* If we found his mac address and his mac address is NOT the * same as the guy we got this frame from, then set * MTF PROXY
*/
H (at && atm bcmp((caddr t) src, (caddr t) aa->aa sender mac, (u intrskeof aa->aa sender mac~) at-~aate flags l= MTF PROXY, reply:
/*
* Make sure that you are try~ng to resolve a iMAC address vs * some other type of address.
*/ ~
if (aa->aa msg type != ATM ARP REQUEST) goto drop;

W O 94/07316 2 1 4 4 1 5 I PC~r/US93/08674 atmarp.c if (latm bclllp(~ry~:L mac, &atp->ac mac, (u int) ~keor(l~,y~l mac)) atm~mac ieamed on non atm inl~rr~ce(k~Jet mac)) * Either we are the target of the arp request or we * found the tarç~et mac address is in our forwarding * d 1 Ace and it was leamed on a non-ATM In~ Irdce * so we send a proxy atm arp .t:sponse ber~ll~e the * atm arp request can not be forwardeci onto that * link.
*/
sport = 8atp->ati port;
else goto drop;
/*
* We have decided to respond. Tum the request Into a * l~sponse by copying the sender s port address into the * target port adr. Copy the senders protocoi (MAC) address * Into the target address. Copy the target protocol address * (target mac) Tnto the senders protocol address and copy * the port selected above into the senders port address.
*/
atm bcopy((caddr_t) aa-~aa_sender port, (caddr t) aa-~aa target port, TU_int) sizeof(aa->aa_sender por~); ~ ~ ~
atm bcopy((caddr t) aa->aa_sender mac, (caddr t) aa->aa target mac, TU int) sizeof(aa->aa sender ma~i));
atm bcopy((caddr t) target mac, (caddr t) aa->aa sender mac, TU Int) sizeof(aa->aa sender mac));
atm bcopy((caddr t) sport, (caddr t) aa->aa sender port, TU int) sizeof(aa->aa sender port));
aa->aa msg type = htons(ATM ARP REPLY);
/* go ahead and send it */
atm send arp(atp, (caddr t) aa->aa target mac, aa, skeof(*aa));
retum;
drop:
atm free msg((char *) aa);
return;

* atm arptab allocO allocates an atm arp tabie for the atmif * structure atp and schedules the first first timeout for that atm * arp table. Each atm arp table has uts tlmeouts scheduled * sei~r~lely. This is an attempt to spread signaiing traffic out * when there are multiple LANs. Zero is retumed if no table could * be allocated.
*/

W O 94/07316 PC~r/US93/08674 2 1 1 ~
atmarp.c struct aate *
atm arptab ~ ~. (rtp) struct atrnH *atp;
struct aate *at;
at = 8atm aate[N AATE S * atm arptabsl;
H (atm arptabs == ATM ARP TA~LES) return O;
atp->ati arptab = at;
atm sched timeoutptr);
atm arptabs+~;
return at;
}

/*
* atm aate freeO ~s called when an atm arp table entry ~s no longer * in use. If a VC is re~rt:nced its re~e,~nce count is dec,t:r"~,ded.
* If the VC s re~rt:"ce goes to zero atm releaseO Is called to * release the VC.
*/
atm aate free(at) struct aate *at;
TR2(TL3 atm aate free(%s / %s)\n atm mac sprinff(at->aate macaddr 6) svc_e164 ntoa(&at->aate cl"~add,));
ASSERT((at->aate flags & AATF MULTICAST) = = O);
at->aate timer = at->aate flags~- O;
H (at->aate vcte && (svc dec(at->aate vcee) == O)) atm rPie~Re(~t->aate vcte VC IDLE~
at->aate vcte = O;
}

/*
* Enter a new address ~n aate push~ng out the oldest entry from the * bucket H there is no room. Th~s always succe~c s~nce no bucket * can be completely filled with pen. auell~ entries (except from * atm arpioctl when test~ng whether another p~-..,ant~ entry will * fit).
*/
struct aate *
atm aate_alloc(at addr) struct aate *at; /* base of aate table for this lan */
u char *addr;
{ ~nt hlwater = O;
struct aate *victum = O *end = &atlN AATE S];
.

W O 94/07316 - 2 1 4 4 1 ~ 4 PC~r/US93/08674 atmarp.c TR1(TL3 ~atm aate alloc(96s)\n atm mac s,~rl,nr(add~, 6));
while (at < end) {
H (at-~aate flags =5 O) goto found;
H ((at->aate flags & MTF MULTICAST) == O
&& (at->aate timer >- hiwater)) {
- hiwater = at->aate timer;
victum = at;
at++;
if (!victum) return O;
at = victum;
atm aate free(at);
found:
atm bcopy((caddr t) addr (caddr t) at->aate macaddr TU int) skeur(~l->aate ",acad~)); ~
at->aate flags = MTF INUSE;
at-~aate~vcte = o;
return (at~;

* a~ a~ ashO - algoli~l",licly ~ene,~les an ATM multicast address * from a 48 bit address. If the number of multicast circuits * supported on this LAN (ati mcasts) is O then use all 48 bits of * the MAC multicast address. The asumption being the network Is * providing multicast service via a se~ver with no limit to number * of multicast conne~iol1s available to each station. If ati mcasts * is greater than zero then the 48 bit address is folded into a * u"~ "ed 32 bit integer by exclusive or'ing the first 2 bytes into * the last two bytes. The resulting ~nteger ~s divided by at~ mcasts * and the resulting number is used as the ATM multicast address.
*/
J,,,I,asl,(atp mac port) struct atmH *atp;
u char *mac;
struct atm addr *port;
port->aa long[O] = O; /* clear flrst word of address *~' H (atp->ati mcasts == O) {
atm bcopy(mac, &port->aa byte[ATM FIRST MiAC] 6);
} else {
port->aa lon l1] = ((macl2] << 24) (~mac 3] ^ mac[1~ 16) ((mac 0] ^ mac[4]) < < 8) (mac[ ]));
port->aa long[1] %= atp->ati mcasts;

W O 94/07316 PC~r/US93/08674 2 1 ~ ~ 1 5 l¦ G
atmarp.c /*
* Thls must be flipped In order to get it Into * network byte order htonl(port->aa longl1]) port->aa byte~ATM FIRST NiAC] = 1; /* set multicast bit */
TR1 (TL4, ~computed mcast of 96x\n~, port->aa long[11);
port->aa type = MT i iAC;/* set the type flel~ */

* arp setupO Is called when a new VC is setup. The arptable is * seh.~;hed for entries needing a VC to the peer port. Those entries * are updated to ~ r~nce the new VC.
*/
arp setup(at, vp) struct aate *at;
struct vcte *vp;
int i;
TR1(Ti2, "atm setup(9~s)\n~, svc el64 ntoa~&vp->vcte peer));
for (i = o; i < N MTE S; i+ +, at++) {
if (!(at->aate flags & MTF COMPiTE)) continue;
if (!atm bcmp(&at->aate atmaddr, &vp->vcte peer, s~eof(vp->vcte peer)) 8&
at->aate vcte != vp~ {
at->aate vcte = vp;
svc inc(vp);

} }

* arp releaseO is cailed when a VC Is about to be released. The * arptable is seh.-,-hed for le~e.ences to the VC. Any entries found * are freeci.
/
arp .~ se(~l vp) struct aate *at;
struct vcte *vp;
int l;
TR1(TL2, ~arp ,~lea.,e(%s)\n~, svc ~164 ntoa(&vp->vcte peer));
for(i =O;I < N MTE S;i++.at++)r if (!(at->aate flags &-MTF COMPLETE)) {

21~54 W O 94/07316 PC~r/US93/08674 6~- ,' . 1`;
atmarp.c ASSERT(at->aate vcte==~);
continue;
H (at->aate vcte l= vp) continue;
at->aate vcte ~ 0;
svc decrvp);
H (~t->aate flags & MTF MUUICAST) == 0) atm aate free(at); /* must dear aate vcte *~irst */
TR1(rL2 ~arp release: sklpped MTF MULTICAST at=%x\n~ at);

ASSERT(vp- vcte refcnt == 0);
}

int atmarp timeol = 24; /* ~dle timeout */
int atmarp~timeo2 = 3; /* i cor. ~L timeout */
extern int hz;
/*
* atm al l li ne. O scans arp tables for active the ATM LAN atp. VCs ar * e~ lished fo ley:~.t rad multicast ad~ ~sses H none exist. Atm * arp enrties for none ~ .tel~d ad i ~sses are timed out. When the * last rer~ ce to a VC ~s freed that VC ~s released (atm aate free * does this).
*/
atm a ~li )e (atp) struct atmif *atp;

struct aate *at = atp->ati arptab *end;
int s;
TR1(TL3 ~atm arptimer(96x)\n at);
atm sched tin-eol t(~tr);
if (atp->ati state == ATS INACTlVq retum;
s = splimp0;
end = 8at[N MTE Sl;
for (; at < en~; at++) {
/* set up multicast circuits which have been released */
if ((at->aate flags & MTF MULTICAST) 8&
(at->aate vcte == 0 Ir ((1 << at->aate vcte->vcte state) 8 VCS DEAD OR DYING))) {
atm initiate setup~atp at);
continue;
if (at->aate flags == 0 l l (at->aate flags ~ MTF MULTICAST)) WO 94/07316 ` PCI'/US93/08674 214415~ ~
G~
atmarp.c continue;
at->aate timer++;
K (at->aate fla~s & MTF COMPLETE) {
if (at->aate timer >= atmarp timeo1) atm aate free(at);
} else if ~at->aate timer ~= atmar~ timeo2) } atm-aate-free(aq;
} splx(s);

WO 94/07316 2 ~ 4 ~ 1 ~ 4 PCl/US93/08674 atmarp.h /* atmarp.h * COPYfllGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
#ifndef RT68K
#Include ~sys/types.h~
#else ~include ~stdint.h>
#endif /*
* ATM Address Res~ nion Protocol (or ATM ARP) Definitlons.
*/
#define ETHERTYPE ATMMAC 0x0805 #define ARPHRD ATM 16 /*
* ATM Address Reso'ution Protocol.
*/
struct atm arp {
u short aa llp; /* lower layer protocol */
u short aa~ulp; /* upper layer protovol */
u char aa llp len;
u char aa~ulp len;
u short aa msg type;
u char aa sender port[8];
u char aa sender mac[6];
u char aa target port[8];
u char aa target mac[6];
};
/* aa msg type' s */
#define ATM ARP REQUEST 1 #define ATM ARP-REPLY 2 /*
* MAC to ATM address ,~ ution table, atm arp table entry aate.
*/
struct aate {
struct atm addr aate ~I",ad.ll, /* port address */
struct vcte *aate vcte; /* vcte ,~r~nce */
u char aate ,"acad.l~ [6]; /* mac address */
u char aate timer; /* ticks */
u char aate flags; /* flags */
/* aate flags field values */
#define MTF INUSE 0x01 #define MTF_COMPLETE 0x02 #define MTF MULTICAST 0x10 #define ATF IjjlULTI MTF MULTICAST
#define MTF PROXY 0x20 -WO 94/07316 PCI'/US93/08674 2~154 . ~
~LI nar,u.h #define MTF RESOLVING Ox40 struct aate *atm aate ailocO, *atm arptab lookO, *atm a~rtsul~eO;
struct aate *atm arptab allocO, *atm flnd atO;
extern struct aate atm aate[l #define ATM ARP T~BLi-S ;6 extern int atm arptabs;

WO 94/07316 2 1 4 ~ 1 5 4 PCI`/US93/0867~

bitS.C
~1-/* bits.c * COPYRIGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
*/
AAAAAAAAAAAAAAAAAA~AAAAAAAAAAAAtNL,~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
#ifndef UNIX
#define ERRLOG p~ t ib~;
#deflne prinff ~.,i"ldl,g #endif /* ifndef UNIX */
#include <stdint.h>
#include ~bits.h~
bits get bit(bits, ske) bits t *bits;
int ske;
int max bit;
int ret;~
int ';
bits t mask;
max bit = size * 8 * SIZE BITS;
for (ret = 0; ret < max bit, ret+ +) {
BITS GET I MASK~et, i, mask);
if ((bits[i] & mask) == 0) {
bits[i] I= mask;
return (ret);
return (-1);

bits tst bit(bit, bits, ske) int ~ bit;
bits t *bits;
int ske;
int ret;
Int l;
bits t mask;
BITS GEr I MASK(bit, i, mask)-ret - i < size && (bits[i] & mask) I= 0;
return (ret);

WO 94/07316 PCr/US93/08674 1 5 4 7~
bitS.c ~2-bits alloc bit(bit, bits, ske) int bit;
bits t *bits;
int ske;
Int ret;
Int i;
bits t mask;
if (!bits tst bit(bit, bits, ske)) {
BITS G~T I MASK(bit, i, mask);
If (i < sker~
bits[i] I= mask;
return (-1);
} else {
return (O);
}

return (O);
}

bits free bit(bit, bits, ske) Int bit;
bits t *bits;
int ske;
int i;
bits t mask;
BITS Gi~r I MASK(bit, i, mask);
if (i < ske~
bits[i] &= ~mask;
}

print bits(bits, ske) bEs t ~bits;
Int~ size;
int j;
for (i = O; i < ske; i++) {
if (bits[i] == ) {
prinff~OxO ~);
} else {
printf(~Ox%08x~, bits[i]);
}

WO 94/07316 2 1 4 ~ PCI~/US93/08674 .
7/
bits.h /* bits.h * COPYRIGHT 1992 ADAPTIVE CORPORATION
- * ALL RIGHTS RESERVED
*/
II.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcNuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~AAAAAAA/
#~ndef BITS H
~deflne BITS H
typedef tUlNT32 bits t;
#define SIZE BITS (sizeof(bits t)) #define BITS GET I MASK(bit, i, mask) \
((i) = (bit) / (8 * ~IZE BITS),\
(mask) = (bits t)ny~ooooooo > > ((bit) 96 (8 * SIZE BITS))) #endif /* ifdef BITS H */

W O 94/07316 PC~r/US93/08674 2~15'1 ~ --if atm.c ~ -34-/* if atm.c * COPYRlGi-iT 1992 ADAPTIVE CORPORATION
* Ail RIGHTS RESERVED
*
* This file contains the oper.lli..g specific routine for the ATM i~ AAC
* for UNIX. The routines defined here are: atm attachO is cailed * once per phys i/f at initiaiization.
*

* if set macO is cailed get a MAC address from the OS.
* if add ianO is notify the OS an ATM i AN is ACTIVE.
* if delete ianO is notify the OS an ATM i~i is INACTIVE.
* atm_free packetsO is calleci to free packets queued on a VC.
* atm append packetO appends a packet on VC til it comes up.
* atm send packetsO is called when a VC becor.-es e~bli~l1ed.
* atm settimeO Copy OS notion of time Into long array of 2.
* atm sched timeoutO schedule the OS to call atm ~.,~i...t:.O.
* svc sched timeoutO schedule the OS to call svc timeoutO.
* svc initO a'~cr~trs global memory area for ATM signaling.
* svc report version conflictO report sl~ aii.,g version conflicts to * atm alloc msgO ~ 'Icr~t~s a msg buffer large enough for signai PDUs.
* atm free mscgO frees message memory pointed to by cp.
* atm alloc bytesO is used to ailocate memory for data structures * aai send msgO sends the pse~ d aal payioad on a VC.
* atm send arpO send a frame enr~rs~ rlg in 802.6/ilC/SNAP type=ARP.
* atm mac inputO handles aai payioads with 802.6 PDUs (ATM i~N).
* svc mac inputO handles aai payioads with SVC PDUs.

WO 94/07316 2 1 ~ l Pcr/usg3/o8674 if atm.c _~ , . .. .

statle ehar seesld~] = ~96A96~;
#ifndef INEr #define INET /* only support Intemet a i i es~l g */
#endK
#indude ù ./sys/param.h~
#inelude ~. ./sys/systm.h~
#inedude ~../sys/mbuf.h~
#indude ~../sys/socket h~
#inelude ../sys/ermo.h~
#Inelude ~../sys/loeti.h~
#Include ../net/if.h~
~include ~../net/netisr.hY
#include ~../net/route.h~
#Include~../net/if arp.h #includeU../sun/ope plO I.h #inelude U../sun4e/mmu.h #ifdef INET
#inelude ~../netlnet/in.h~
#inelude~../netinet/in systm.hY
#ineludeY../netlnet/in var.h~
#include U../netinet/ip~
#endif #include Udebug.hu #include Uniu.h~
#include unipdu.h~
#include atm.h~
#include Ulle.h~
#include svc.hU
#includeUsvc uti.hU
#includeUif niuarp.hU
#include Uatmarp.h~
#include ~if niu h~
#include~K niuio.h~
#inelude if atm hu #inelude ~sys/time.h~
Int atm watehO;
int sve pem= 1;
extem Int atm traee;
#define TL1 #defineTL2 atm trace>1 #defineTL3 atm trace 2 #defineTL4 atm trace~3 #define TL5 atrn trace>4 WO 94/07316 ~ PCI/US93/08674 2 1 4 ~
if atm.c struet niu arpeom niu a-i eol,ls[NNlU * iNATMS];
* atm attaehO Is eailed when the maximum number of ailowed ATM LANs * for a speeHie l~ .r~lee have been determineci. atm nnius must be * patehed with the number of ATM i ANs per physieai~ ,iaee before * bootlng. Only that number of ATM i~is wlll be eonfigured ~ regardless of ATM LAN eor~fiDllrptior~ ~tlol1 providled by the * i MI eonficJuration protoeol. ( Ne eould dynamieaily attaeh and * deti-aeh Hnet struetures BUT the there is a signHicant * p~l y other eode In the system assumes Hnets are are statie * after boot. So Hnets are statleaily linked once at boot.) */
atm ~U~ch(pe) struet peH *pe;
{

struet Hnet *ifp;
struet atmif *atp;
Int lan, Hunit;
int , luoutrut0, ~ 'c - 0, mae[2];
atm initO;
for ran = 0; lan < pe->pe num lans; lan++) {
ifunit = atm glob->atm~used++;
atp = &atm glob->atmK~funitl;
atp->ati ac~- &niu a,i cor"~[ifunit];
niu a, i ec,r"s[ifunit].ae atmif = atp;
Hp - &atp->ati ac->ac H;
Hp->H unit = Hunit;
if (niu 1nfo[pe-> pc num].",acad-l- [0] l l niu info[pc->pe num].",acadd,[1]) {
mae10 = niu in~[pe->pc num].",acadd~[0];
mac[1 = niu~info[pe->pe~num].r"aeadd,[1] + lan;
beopy;((ehar *) mae) + 2 ((struet niu arpeom *) Hp)->ae enaddr, 6);
} else niu get enaddr(ifp->H unit, ~ (struct niu arpeom *) Hp)->ae enaddr);
ifp->if name = ~aa~;
Hp->K mtu = pe->pe hw max mtu;
ifp->if flags = IFF B~oAEicAsT I IFF NOTRAILERS;
Hp->H loetl = r ~ Y, Hp->H output = I- lolltrllt;
ifp->H promise= 1;
Hp->H timer= 1;
Hp->if snd.Hq_rnaxlen = IFQ MAXLEN;
Hp->if watehdo~ = atm wateh;
~ attaeh(ifp);
} atm_attaCh ian(atp, pe3;

WO 94/07316 2 1 qL 1 t ~ 4 PCI`/US93/08674 ;
if atm.c ~7-}

int awi = o; /* atm watch Inter~ai, for those who * can not type */
int awittg[NNlU]; /* atm watch intervai ticks to go */
atm watch(ifunit) Int Nunit;
{

struct ifnet *ifp = (struct Hnet *) & niu a"~coi.,s[ifunit];
int iounit = NIU_IFUNIT TO i~5UNlT(ifunit);
int s;
ifp->if timer= 1;
if (ifunit l= o) return O;
if (awi == O) retum O;
if (awittg[iounit] <= O) ~
p~i"lr( r~s~ g unit %d from watchdog\n~, iounit);
s = splimpO;
(*niu info[iounit].reset) (iounit, 1);
if (niu info[iounit].type == NIU TYPE HW~ {
} setup_rxbuf(&niu info[iounit]S~ ~
splx(s);
awittg[iounit] = awl;
} else awittg[iounit]-;
return o;

}

/*
* set ati mac from value provided by os H set mac(atp) struct atmif *atp;
bzero(&atp->ati mac, skeof(struct atm addr));
atp->ati mac.aa type = MT iUlAC;
bcopy(atp-~ati ac->ac enaddr, &atp->atl mac.aa byte[ATi i FIRST i iAC], 6);

* ii add ianO is notify the OS an ATM i AN is ACTIVE. (and * con iit~onally set mtu ske) if add ian(atp, mtu) struct atmif *atp;

2 1 ~ c if atm.c int mtu;
H (mtu && mtu <= atp->ati pcH->pc hw max mtu) ((struct Hnet *) atp->ati ac)->K mtu = mtu;
((struct Hnet *) atp->ati ac)->H fiags I = IFF RUNNING;

/
* H delete ianO is notify the OS an ATM iAN is INACTIVE.
/
H delete ian(atp, mtu) struct atmif *atp;
((struct ifnet *) atp-~ati ac)->H fiags &= -IFF RUNNING;
}

/*
* convert os Hunit to atmH index, th~s is not cailed very often.
H get ian(atp) struct atmif *atp;
int i;
struct atmif *atpO;
for (i = O, atpo = atp->ati pcif->pc atmH;
atpO J= atp;
atpO = atpO->ati next, i+ +);
retum i;
/*
* atm free p~ket~0 is called to free packets queued on a VC.

#Hndef KERNEL
#define m freem(m) atm free msg(m) #endH
atm free packets(vp) struct vcte *vp;
struct mbuf *m = (struct mbuf *) vp->vcte packet;
struct mbuf *mO;
while (m) {
mO = m->m act;
m freem(m);~
m = mO;
vp->vcte packet = O;

WO 94/07316 2 1 4 ~ 1 ~ 4 P~/us93~0~674 .

~ . ~ , ..
if atm.c I .

* atm append packetO appends a packet on VC til it comes up. (WB
- * only queue two pA~ ~-s) */
atm append packet(vp m) struct vcte *vp;
struct mbuf *m;
{

m->m act = O;
H (vp-~vcte packet) {
H (((struct mbuf *) vp-~vcte packet)->m act l= O) {
m freem(m);
return;
} else ((struct mbuf *) vp->vcte packet)->m act = m;
} else vp-~vcte packet = (caddr t) m;
svc glob->svcst~tn;neueci frames+~;
return;
/*
* atm send pack~tco is called when a VC beco~"es established. Any * queueci packets are sent.
*/
atm send packets(vp) struct vcte *vp;
struct mbuf *m = (struct mbuf *) vp-~vcte packet;
struct mbuf *mO;

while (m) {
mO = m->m act;
aal send msg(vp vp->vcte atmif->ati mid (caddr t) m LEh FOR i iBUF PTRS);
m = mO;
vp-~vcte packet = O;

* atm settimeO Copy OS notion of time Tnto long array of 2.
atm settlme(t) struct timeval *t;
extern struct timeval time;
int spl;
spl = spl70;

W O 94/07316 ~. PC~r/US93/08674 ?~
214~1~4 if atm.c *t = tlme;
splx(spl);

Int atm ~ erO; *
int atrn arp rns per tick = 10000; /* once every 10 seconds /
* atm sched timeoutO schedule the OS to call atm a"~il"~,O.
/
atm sched tirneout(~tr) reglster struct atmH *atp;
#Hdef notdef /* l assumed tcp start timerO takes seconds ?? */
tcp start timer(&~atp->tmr entry) atm arp ms per tick 710 ? ? ?, atm a" ~U" ,er (caddr t) atp);
#else timeout(atm arptimer (caddr t) atp atm arp ms per tick * hz7 1000);
#endif }

/*
* returns true ff we are forwarding frames out a specHic non-ATM
* t"~ ace. Olhel~ ,e returns false.

*/
atm mac learned on non atm i,~ ace(mac) caddr t mac {

return O;

* atm send arpO send a frame en~rsl''-~ing in 802.6/ilC/SNAP
* typecARF
atm send arp(atp, mac, msg, len) struct atmH *atp;
caddr t msg, mac;
{
struct soc~ hl~ sa;
m = dtom(msg);
m->m len = len;
ASSERT(ien < = Mi EN);
sa.sa family = AF UNSPEC;

W O 94/07316 2 1 ~ I 1 5 l1 PC~r/US93/08674 7~
if atm.c ~1-((struct ether header *) sa.sa data)-~ether type =
ETHERTYFE ARP;
bcopy(mac, ((struct ether header *) sa.sa data)->ether dhost, 6);
nillolltrllt(~tr->atl ac, m, &sa);

* aal send msgO sends the pse~- f;ed aal payioad on a VC. Sends a * .,.essage, msg, of length, len, byte on VC vp using multiplex-id, * mid. If len Is i FN FOR MBUF PTR then msg is a polnter to an mbuf * chain. Oll,el~;~.e it is a pointer into an mbuf. There should * probably be se~ le routines for thls...
aal send msg(vp, mid, msg, len) struct vcte *vp;
int mld;
caddr t msg;
Int ~ len;
struct mbuf *m;
struct Knet *Hp;
struct sock~rl-lr aal sa;

H (ien == LEN FOR MBUF PTRS) {
m = (struct mbuf *~ msg;
else {
struct setup *pdu;
pciu = (struct setup *) msg;
TR1 (TL3, ~aal send: %s\n~, svc pdu type str(pdu->lmi pciu type));
if (pdu->lmrpdu type <= LMrPDU LAST) svc glob->svcst~tpclll~ sent[pdu->lmi pdu type]++;
m = dtom(msg);
m->m len = len;
H ((pdu->lmi cref type I pdu->lmi cref vaiue) && TL2) svc trace pdu~pdu, len, O, vp->vcte ovpcl);
vcontr)llt(vp, m, mld);

/*
* atm mac inputO handles aal payloads ,orocessl~g 802.6 & calling * llC. Should be called at SPUMP. Called by deliver packetO.
* atm data indO Is called to process the ATM MAC header and get a * poTnter to the ULC header. Ilc data indO is called to process * the llc frame.
*/

Pcr/US93/08674 21 4 ~ if atm.c atm mac input(vp, mO) s~ruct mbuf *mO;
struct vcte *vp;
{

struct Hnet *Hp;
struct atm header *ah;
struct llc snap *Ip;
u char *src;
u~long *p;
Int mac hdr len;
int prornisc - O;
Hp = (struct Hnet *) ((struct atmif *) vp-~vcte atm-~->ati ac;
Hp->H ii~ck~t~++;
DB1 (DL4, Uaa%d: atm mac input\n~, Hp->H unit);
ah = mtod(mO, struct atm header *);
ASSERT((((u long) ah) & Ox3) == 0);
H (mO->m len ~ LLC LEN + ATM HDR LEN + ah->atm elen * 4) {
DB1 (DL1, "aa%d: atm mac input short frame\n", if p-> if unit);
m freem(mO);
return ENOBUFS;
H (ah->atm dst.aa byte[2] & Ox01) {
H (Iniu findmulti~vp->vcte atmif, &ah->atm dst.aa byte[2])) {
promisc= 1;
} else if (IATM ADDR EQ(ah->atm dst, vp->vcte atmif-~ati mac)) promisc= 1;
ip = (struct llc snap *) ((caddr t) ah + ah->atm elen * 4 +
skeofr*ah));
mac hdr len = (caddr t) Ip- (caddr t) ah;
src- &ah->atm src.aa byte[21;
H (Hp->H promisc) /* assume nit i"L~,idce is active */
niu snEify 8026(Hp, mo, mac hdr ien, prorn;sc);
H (promisc) m freem(mO);
else ~
m adJ(mO, mac hdr len);
K ~ah-~atm pid1 = ~TM PID i LC) m i,~---rlO);
else llc data ind(Hp, mO, src, mac hdr ien, Ip);
return O;
}
/*

2~ 4~ 5~

~/
if atm.c ~ svc mac inputO handles aal payioads with SVC PDUs. Note, SVC PDUs * must fit in one mbuf. Hence the limitation for 4 ATM LANs for * 4.2BSD UNIX impier.,er~li"ns. This could be chan~ed by using * clusters for PDUs.
svc mac_input(vp, m) struct vcte *vp;
struct mbuf *m;
{

int len = m ien(m);
H (len > Mi EN) {
svc glob->svcst~tixiu_too big++;
m ~eem(m);
return O;
}

m = m pullup(m, len);
if (m =- O) {
svc glob->svcst~tixiu lost nomem++;
return O;
ASSERT((mtod(m, int) &3) =- O);
if (m->m next) {
m freem(m->m next);
m->mnext=O;
}

svc pdu(vp->vcte pcif, mtod(m, caddr t), len);

#include "../sys/domaln.h"
extern struct domain sv~ion,ai", pvcdomain;
#define ADDDOMAlN(x) { \
extem struct domain x/**/domain; \
x/**/domain.dom next = domains; \
domains = &x/**~domain; \

/*
* svc initO a"~,~tPs global memory area for ATM siy"al;ng.
extem int tr buf_ske;
struct vcte svc vctesVCTAB SIZE];
Int svc_Init count = O;
struct ulptab svc ~iptablNUUS];
struct atm globs atm globs;
struct tr grobs tr globs;
struct svc globs svc globs;
char svc e164 strl32];
_ svc initO

W O 94/07316 PC~r/US93/08674 2 1 4 ~ P~
if atm.c ~ ,~4 { struct vcte *vp;
int svc mac imiO, svc mac inputO;
if (svc init count) retum;
svc glob->statlc buf = svc e164 str;
svc init count-~i;
bzero(&svc glob-~svcstat, skeof(struct svcstat));
svc glob-~vcte free = svc vctes;
svc glob->vcte base = svc vctes;
svc glob->ulptab = svc ulptab;
svc glob->ulp Inuse = 0;
for Tvp = svc vctes; vp < &svc vctesVCTAB SIZE]; vp+ +) vp->vcte next cref = (struct vcte *) & vp[1~;
(-vp)->vcte next cref = 0;
svc glob->slg ulp = ulp register(LMil L~ ORG, LMI LNil PID, svc mac input, svc mac Iml, 0);
svc glob->svc pc~=
(struct pcif *~atm ailoc bytes(skeof(struct pcif) * NNIU);
bzero((caddr t) svc glob->svc pcif, skeof(struct pc~ * NNIU);
svc glob->svc pcifn = &svc g~ob->svc pcif[NNlU];
svc glob->svc parms = svc pamms;
atm glob->atmif = (struct atmif *) atm alloc bytQs(ci~Pof(struct atmif) * NATMS * NNIU);
bzero~cadd~ t) atm glob->atmif, skeof(struct atrnif) * NATMS * NNIU);
tr init(tr glob, tr buf ske);
AE5DDoA~ AlN(pvc);
ADDDOMAlN(svc);
ADDDOMAlN(llc);
pvc initO;
#if0 atm bzero(p, I) char *p;
{

bzero(p, I);

atm bcopy(s, d, I) char *s, *d;
{

bcopy(s,d,l);
}
atm bcmp(s, d, I) W O 94/07316 2 ~ PC~r/US93/08674 if atm.c char *s *d;
{

retum bcmp(s d I);
~endif .. /
* 8vc sched timeoutO Is called to schedule svc timeoutO to be * called with the argument ~pc" when the next srgnaiing tick tock's.
* On UNIX this is mapped onto timeoutO convertlng svc ms per tick * to Hertz. Presumably MS-DOS uses Avls baseci timeouts.
*/
svc sched timeout(pc) struct pclf *pc;
Int svc timeoutO;
timeout(svc timeout (caddr t) pc (svc ms per tick * hz) /1000) * svc report version conflictO is called everytime a s;~"ali"g PDU
* with an unsupported vers~on is received. It should report this * uslng the ap; ropr~dle OS routines. For UNIX we printf to the *jconsole no more than once every 15 seconds.
struct timeval svc last conflict;
{svc-report-version-confllcto extern struct timeval time-if ((svc last conflict.tv sec + -i5) < time.tv sec) {
printf( niuo: s;~lldlillg protocol version conflict\n );
svc iast conflict.tv sec = time.tv sec;

* atm alloc msgO: ~c ~es a msg buffer large enough for signai caddr t {atm_aToC_ms~o struct mbuf *m;
m = m get(M DONTWAIT MT DATA);

WO 94/07316 PCI'/US93/08674 2~1S'~ ~ ~
if atm.c H (!m) return O;
m->m off= MMINOFF;
m-~rn~ien = O;
return mtod(m, caddr t);

struct mbuf *atm lastfm;
/*
* atm free msgO frees ~I~essage memory pointed to by cp.
atm free msg(cp) char *cp;
ASSERT(IVALID VP((struct vcte *) cp));
atm lastfm = dtom(cp);
} m_freem(atm_lasffm);

/
* atm alloc bytesO is used to allocate memory for data structures * whic-h are never freed, e.g., svc pcH tables.
caddr t atm aTioc bytes(n) {

return kmem alloc(n);

int atm trace to console = O;
/*
* Convert address to a hex byte str~ng. The length of the address * is specifl~ with the argument len.
*/
char *
atm mac sprintf(ap, len) u char *ap;
Int l;
char *cp = atm glob->static buf;
static char digits~] - Lo123456789~l'od~;
for(i = O; I < len; I++) {
*cp++ = digits[*ap >> 4];
*cp+ + = digits[*ap+ + & Oxf~;
*cp+ + = ':';
*--cp = O;
return atm glob-> static buf;

W O 94/07316 2 1 4 !~ PC~r/US93/08674 .

if atm.c !l, " ,l i ~' '.

.

214 ~ ~ 5 ~ if atm_.h /* H atm.h * COPYRlGi IT 1992 ADAi'TlVE CORPORATION
* Ail RlGi-iTS RESERVED
/*
#ifndef NIU ATM H
#define NIU ATM~i Inciuded #Include ~bytes.h~
#Include "unipdu.h~
/*
* atm mac servlce l,ltt:.race (asl). Thls Is the same as an ethemet * header so that upper layers can s~mply assume ATM Is an ethemet.
*/
struct atmmsi ~
u char asi dst[6];
u char asi src[6];
u short asi type;
};
/*
* Structure of an ATM mac header for aai type 4, this is an 8Q2.6 * header.
*/
struct atm header {
struct atm addr atm cst;
struct atm addr atm src;
union {
struct {
u int mcb pid:6;
u int mcb pad:2;
u Int mcb delay:3;
u int mcb loss:1;
u int mcb crc:1;
u int mcb elen:3;
u int mcb pad1:16;
} mcbits;
u int atm mcb lon~;
} un_mc~;
};
#define atm mcbits un mcb.atm mcb long #define atm~elen un rncb~mcbits~mcb elen #define atrn crc un mcb.mcbits.mcb crc #define atm~oss un~mcb.mcbits.mci~ loss #define atrn delay un mcb.mcbits.mcb delay #define atm pid un mcb.mcbits.mcb pid WO 94/07316 2 1 ~ 4 i ~ 4 PCI/US93/08674 8jt if atm_.h #define ATM PID i- LC 1 /* protocol ID for ilC */
#define ATM MCBITS NOCRC 0x04000000 /* protocol id 1 */
#define ATM HDR LEN skeof(struct atm header) #define ATM PAD SHIFT 24 -/*

* The only header ~":,ion defined Is a retum port address. The * length must be set to ATME RPA SIZE. Pad exists to get the 64 bit * address 64 bit aligned relative to the atm header.

*/

struct atm header ext {

u char atme len;

u char atme type;

u char atme~pad[2]; /* need not be zeros (nnbz) */

struct atm addr atme rpa; /* retum port address */

}, ~define ATME RPA TYPE 112 /* out of SMDS range */
#define ATME RPA BYTES sizeof(struct atm header ext) #define ATMi ~RPA~WORDS ((skeof(struct atm header ext) +3)/4) /*
* Callers to atm data reqO must ensure atieast ATM DATA REQ ROOM
* bytes are available in front of the packet data.

#define ATM DATA REQ ROOM (ATM HDR LEN+LLC SNAP i FN+ATME RPA BYTES) * multicast address structures are linked to atm arptabs which are * marked ATF MULTI. Such entries are not timed out nor are they * freed when underiying VCs are released. atm delete lanO free s * the ATF_MULTI atm arptab entries and atm add lan~ &
* atm nlu to niu0 rc . . ~~e them and re initiate iviC VCs for the * re~ .tel~ci adci,~sses.
*/
struct mcaddr {
u char mc enaddr[6]; /* multicast address */
u short mc count; /* leielt:l,ce count */
struct aate *mc at; /* multicast VC */

#define MCADDRiUAX 64 /* multicast addr table length */
#define MCCOUNTi~W~ (32*1024-1) /* multicast addr max * ,~ nce count */

* atmif one per atm lan, used by atm lan layer ~ /
struct atmif {
struct niu arpcom *ati ac; /* contains arp and ifnet WO 94/07316 PCI'/US93/08674 214 115ll ~P
if atm_.h * structures */
struct atmif *ati next; /* linked off pcif structure */
u short atl state; /* basicaily do we know WilO
*weare*/
u short ati mid;/* mid used for m~ r~ct frames */
u short ati mcasts; /* max # multicasts circuits * configured */
struct atm addr ati port;
struct atm addr atrmac;
#define ac mac ati mac.aa byte[2]
struct pcif *ati pcif;
struct aate *atr arptab; /* set at initiai~liol- */
Int ati num mcasts;
struct mcaddr ati . cadLi ~;[MCADDRMAX~;
}.
/* ati state */
#defins ATS INACTIVE O
#define ATS ACTIVE 3 /*
* global data structure for r/w variables and variables explicitiy * initialized.
*/
#include llc.h~
struct atm globs {
struct if_tr hdr *Itrb-struct atml~ *atmif int atmifn;
Int atmif used;
struct llc snap llc def;
struct atm addr atm br~ c~
struct atm addr atm null;
struct ulptab *atm ulp;
Int atm inEiaiked;
char static buf[32];
};
#ifndef RT68K
extern struct atm globs atm globs;
#define atm glob (8atm globs) #else #define atm glob atm get globO
struct atm gTobs *atm get globO;
#endif WO 94/07316 2 1 ~ ~ 1 5 ~ PCr/US93/08674 ~9 . 1 ~. ' ` .~
if atm .h #define LEN FOR MBUF PTRS Q~5~oon~
#define HASH MULTICAST ADDRESS(x) ((x)~Oxf~
caddr t atm alloc ms30, atm alloc bytesO;
#define NATMS ~4 /* rnax # of A-TM lans per physical * In~ ce */
#define e160 ntoa svc e164 ntoa/* these are really E.164 addl~sses */
~endif /* NIU ATM H */

W O 94/07316 PC~r/US93/08674 211415ll 9 if niu.c /* if niu.c * COPYRIGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
/*
* Desc l~lol1. This file contains the ne~Nork l~lt~ race portlon of * the nlu device driver.
*/
static char sccsid[] = ~96A%~;

#ifndef KERNEL
#define Ki_RNEL
#endff #ifndef INET
#define INET /* only support internet add eg~;l g */
#endif #include ~../sys/param.h~
#include ~../sys/systm.h #include ~../sys/mbuf.h~
#include ~../sys/socket.h~
~include ~../sys/errno.h~
#include ../sys/iocti.h~
#include ../sys/time.hh #include ~../sys/kernel.h~
#include ../sun4c/psi.h~
#include ~../net/if.h #include ../net/netisr.h~
#include ~../net/route.h~
#Tnclude ../net/if arp.h~
#include ../sun/opel p lolll.h~
#include ~../sundev/mbvar.h~
#Include ~../sun4c/mmu.h~
#ifdef INET
#include ~../netine~/in.h~
#inciude~../netinet/in systm.h~
#indude~../net~net/in var.h~
#include ~../netinet/ip h~
#endif #~nclude ~debug.h~
#include niu.h~
#Include ~unipdu.h~

W O 94/07316 2 1 4 ~ 1 5 4 PC~r/US93/08674 9/ . - .
if_niu.c #include atm.h #Include ~llc.h~
#include ~svc.h~
#include~if niuarp.h~
#include ~atmarp.h~
$1nciude H niu.h~
#include~if niuio.h~
#include Vtrace.h~
#Include~../net/nit ff.h~
#include ~snit.h~
int aal trace enable= 1;
/* debugging and tracing stuff */
#define DL1 #define DL2 niu debug> 1 #define DL3 niu debug>2 #define DL4 niu debug>3 #define DL5 niu debug>4 #define TL1 #defineTL2 niu trace>1 #deflne TL3 niu trace>2 #define TL4 niu trace>3 #define TL5 niu trace>4 #define DRAIN TIME 4 /* the SIOCNIUDBUG will set ALL debugging and tracing levels */
int niu debug = 1; /* conveys i po~ driver * i.,r~""dLi~".*/
int niu trace = 1; /* show excessive detdil of the * p~oyldln stream */
extern int arp debug;
extern int arp trace;
extern int drv debug;
extern int drv trace;
extern int dump fiag;
int niumtu = 2000;
int niu unit count = 0; /* totai number of sw and hw * units installed */
struct niu dev niu ~nfolNNlU]; /* network l~ ~rrace device structure */
int ~ nluo tj utO n lSCh,Ct10;
/*
* Name: n;uol~tpl-t * Input: *ifp - pointer to network i ~t Irace to * use. m - mbuf pointer containing packet to be sent.
* dst - ip address of de~i dlion.
*

* Output: None.

W O 94/07316 PC~r/US93/08674 2 ~
if niu.c *

* Retum: 0 - no error. Error * Unix error code.
* Des.;,;,vlion: This routine is cailed with a frame and a de:.ti,ultion * address. Ap~,oprh~ address r~s~ n is pe,ru""ed for the * de~ ~lion ad i,~sses until a VCI is ~ ,ed. The families * supported are: AF INi T: An IP address ~s resloved using MP
* Into a 48 bit address. AF UNSPEC: A 48 bit address is resloved * into a 60 bit address and LLC/SNAi header is added. AF NS: A 48 * bit address is resloved ~nto a 60 bit address but no ilC/~NAP
* header is added. AF CCITT: A 60 bit l- le"holle number Is rescdved * ~nto a VCI using the port address to vcl tables. AF Di i: A VCI
* is sl~, ie~ No 1~5- -nion Is pe,iur",ed. The VCI ~s in * sock~dd, aal structure. AF INi_T, AF UNSPEC anci AF NS frames are * enc~rsu -~ as per 802.6. 0ther address families are assumed to * be enc~psl -~-ci already.
*

* Note: The above families overioad existing AF x~ values. Aiso raw * aal frames get queued on the first atmlan s Knet send queue for * lack of a better place to put them.
*/
Int niu reset on full = 0, niu auto resets = 0;
Int willie panic = 0;
~o~p~(ifp, m, dstin) struct ifnet *ifp;
register struct mbuf *m;
struct soc'~ *dstin;
int U~ ~, s len, ifunit rate;
struct vcte *vp;
struct ifqueue *ifq;
struct sock~d '. Idst;
struct mbuf *mh;
struct in addr Idst;
u char endestl61;
struct niu arpcom *ac;
struct aal parms *ap;
struct llc snap *Ic;
Int ~ iounit, error = 0;
iounit = NIU IFUNIT TO lOUNlT(if~if unit);
/* check H network is up */
TR4(TL3, ~niuolltpl~(%x~ %x %x af=%d)\n~
ifp m dstin dstin-~sa family);
K ((ifp->if flags & IFF UP~== 0 &&
dstin->sa family 1- AF DU) {

WO 94/07316 2 1 4 1 ~ 5 4 PCI~/US93/08674 ~3 if niu.c ~;

m r,e~",(~");
error= ENETDOWN;
goto rtn;
}
ifunit- Kp->H unit;
ac = &niu ~"-co,-,~[ifunit];
s = splr(ipltospl(nlu Info[iounit].priority));
#ifdef INET
if (dstin->sa famlly == AF INEr) {
Idst = ((struct sock ~ n *) dstin)->sln addr;
DR~(n! ~ ~aa96d: dest - %s\n~, Kunit, Inet rtoa(idst));
if (Iniu &"~ sol~(ac, m, &Idst, Idst.sa data, &usetrallers)) {
goto rts;
((struct ether header *) Idst.sa data)->ether type =
ETHERTYi'E IP;
Idst.sa family - AF UNSPEC;
dstin - &Idst;
} else #endif H (dstin-> sa family ! = AF DLi &&
dstin-> sa family I = AF NS &&
dstin-~sa family l= AF UNSPEC) {
prinff("aa96d: can't handle af~bd\n~, ifp->if unit, dstin->sa family);
m freem(m);
niu info[iounit].stats.errors++;
error= EAFNOSUPPORT;
goto rts;
/*
* dstin.sa data con~"s an ethernet header w/o a source adr * & type. ~unless AF DLi in which case we have a vci...) */
if ((m->m off & Ox3) 1 I M i-iASCL(m) 1 1 /* make room */
(m->rn off - MMlNOFFr~ (ATM DATA REQ ROOM +
s~eof(struct aal parms))) {
if ((mh = m get(M DONTWAiT, MT DATA)) == NUil) {
m freem~m);
error= ENOBUFS;
goto rts;
}
mh->m len = 0;
mh->m off= MMAXOFF-mh->m~next = m;
m = mh, if (dstin->sa family == AF UNSPEC) {

WO 94/07316 PCI`/US93/08674 .`' ~
f~
~ gL415 ~ if_niu.c /* add ilC and SNAP */
Ic = &(mtod(m, struct llc snap *)1-1]);
*Ic = atm glob-~llc def, Ic-~llc type = ((struct atmmsl *) dstin-~sa data)-~asl type;
m->m off-= skeof(*lc);
m->rn len += skeof(*lc);
len = 0;
for (mh = m; mh; mh = mh->m next) len += mh->m len-if (dstin->sa family =- AF UNSPEC 1 1 dstin->sa family == Af NS) { /* get vci for mac * address */
struct atm header *ah = mtod(m, struct atm header *);
struct aate *aat;
if ((ifp->K fiags & IFF RUNNING) == 0) {
m freem(m);
error= ENETDOWN;
goto rts;
len += skeof(*ah);
ah-;
ah->atm dst.aa long[0] = MT MAC << 28;
bcopy(dstin->sa data, 8ah->atm dst.aa byte[2], 6);
ah->atm src = atm glob->atmif[ifunit].ati mac;
ah->atm mcbits = T(ATM PID ilC < < 2~ +
((4 - (len & 3)) & 3)) < < ATM PAD SHIFT;
ah->atm elen = 0;
m->m o~f-= sizeof(*ah);
m->m len += sizeof(*ah);
aat = atm find at(&atm glob->atmif[ifunit], dstin->sa data);
if (laat I I I(vp - aat->aate vcte)) {
m freem(m);
error= EXDEV;
goto rts;
if (vp->vcte state < VCS ESTAi3) {
atm append packet(vp, m);
goto rts;
} else {
ASSERT(dstin->sa family == AF DU);
vp = ((struct soc~ aal *) dstin)->saal vcte;
if (vp) ASSERT(\/AUD VP(vp));
}
m->m off -= sizeof(struct aal parms);
m->m len += skeof(structaal parms);

W O 94/07316 2 1 4 ~ 1 5 11 PC~r/US93/08674 if niu.c s7-ap = mtod(m, struct aal parms *);
ap->ap mid = atm glob->atmlf[ifunKl.ati mid;
ap->ap vpcl = vp->vcte ovpci;
ap->ap rate = vp-~vcte opeak rate > ~ 4; /* from lK bps to 16K
* bps units *7 if (vp->vcte aal =s 0) ap->ap flags = MLP RAW CEil I AALP CRC NONE;
else ap->ap flags = AALP CRC NONE;
t* lop, i~iucige till rev 2 fred l/f with 960 gets implemented */
if ((I(vi~>vcte pcif->pc flags & PCIF NIU TO NIU)) &8 vp->vcte pcK-~pc s~g->vcte state =- VC~ ACrIVE) ap->ap flags l= A~iW ENAi31E XON XOFF
vp->vcte I)A~ ++;
ff p ~ jf i~4et6+ +;
* if multlcast then frame must be single II"t,aded so used * the atm lan index + 1 to Ind~cate in which outbound queue * the frame should be placed.
*/
ap->ap orderq = (vp->vcte flags & VCTEF MCAST Ci~ENT) ?
(Int) ~p->vcte atmif-atm~glob->atml~ +-1:
Mi P UNORD~RED-ap->ap~orderq = 4; /* ~op, n~u bug requires no more than ~1 vci per rate queue */
ap->ap len = len + sizeof *ap;
* Place packet on i,i~e~ace transmit queue */
ffq = &niu Info[iounit].sendq;
ff (IF QFUrL(ffq)) {
Di30(Di2, n ~on r~t l"~e"ace q full\n );
if (n~u reset on ~ull l l niu ~nfo[iounitl.type == NIU TYPE SW
niu lnfo[rounit].board id-== NIU REV3) {
ASSERT(willie panic -= 0);
while (m) {
m freem(m);
IF DEQUFIJF(i~q m);
IF DROP(ffq);
niu auto resets++;
(*nru Info[iounit].reset) (iounit, 0);
TRl~L1, ~aa%d auto reset\n~, ifi~>K unit);
pri,dr(~aX,d auto reset\n~, ffp->ff un~;
H (niu info[iounit].type == NIU l~PE HW) {
} SetUp-rxbuf(&niu-info[iounitl~ -} else {IF DROP(ffq);
m freem(m);

W O 94/07316 PC~r/US93/08674 2l~ls~ ~ niu.c }
error= ENOBUFS;
} else ~
TR1(lL3, ~%d on queue: ~, Ifp-~H snci.ifq_len);
IF ENQUFIJF(ifq m);
(*niu info[iounit].seu i~ ) (iounit);
rts:
splx(s);
rtn:
TR3(rL3, ~n' lolnrut-~%d~ %d q %d d\n~, error, ifq-~ifq len, Nq->ifq drops);
return error;

* send mbuf chain m on physicai l,nt Irace pc over VC vp using the * aal ~soci ~ with that vp. mid is the multiplex ici for aal 3t4.
* it is ignored for aai 5.
*/
vcoutput(vp, m, mid) struct mbuf *m;
struct vcte *vp;
{ int s, len;
struct ifqueue *ifq;
struct mbuf *mh;
struct aal parms *ap;
int ~ iounit = vp->vcte pcif->pc num;
int error = 0;
ASSERT(\/AUD VP(vp));
s = splr(ipltospl(niu info[iounit].priority));
if ((m->m off & 0x3) 1 I M HASCL(m) l I
(m->rn off - MMINOFF~ skeof(struct aal parms)) {
if ((mh - m get(M DONTWAiT, MT DATA)) == NUUL) {
m r,t:e",~,);
error= ENOBUFS;
goto rts;
mh->m len = 0;
mh->m off = Mfi~W~OFF;
mh->m next = m;
m = mh;
rn->m off-= skeof(structaal-parms);
m->m len + = skeof(struct aai parrns);
ap = mtod(m, struct aai parms *);
ap->ap mid = mid;

WO 94/07316 2 1 ~ 4 1 ~ 9 PCr/US93/08674 ~7 if niu.c ~ t'' ap-~ap vpci = vp-~vcte ovpci;
ap-~ap_rate = vp-~vcte~opeak rate ~ > 4; /* from lK bps to 16K
* bps units *7 - H (vp->vcte aal = = 0) ap-~ap frags = Mi P RAW CEi- L I AALP CRC i iONE;
else ap-~ap fla~qs = MLP CRC NONE;
H ((I(vp-~vcte pcif->pc flags~ PCIF NIU TO i ilU)) 8&
vp->vcte pcH->pc s~g &&
vp-~vcte pcif->pc sig->vcte state == VCS ACTlVq ap->ap flags l= MLP ENAB~E XON XOFF, vp-~vcte opack~++;
/*
* if multicast then frame must be single threaded so used * the atm lan index + 1 to ~ndicate in whlch outbound queue * the frame should be placed.
*/
#if 0 ap->ap orcierq = (vp->vcte flags & VCTEF MCAST Ci iENT) ?
(int) (~p->vcte atmH - atrn~glob->atm-~ + 1:
MLi' UNORDERED;
#endH
ap->ap orderq = 4; /* iopt niu bug requires no more than * 1 vci per rate queue */
for (len = 0, mh = m; mh; mh = mh->m next) len += mh->m ien;
ap-~ap ien = len;
* Place packet on interface transmit queue */
Hq = &niu info[iounH~.sendq;
if (IF QFU~L(ifq)) {
DB0(DL2, "vcouput: interface q full\n~);
if (niu reset on full niu info~lounit].type == NIU TYPE SW
niu~info iounit].board id ==-NlU_R-Ev'3) {
ASSERT,willie panic -= 0);
while (m, {
m freem(m);
IF DEQUEUE(ifq, m);
IF DROP(Hq);
niu auto resets++;
(*n~u info[iounit].reset) (iounit, 0);
TR1 (~L1, ~niu%d auto reset\n~, iounit);
prinff("niu%d auto reset\n~, iounit);
H (niu info[iounit].type == NIU TYPE HW~ {
setup_rxbuf(&niu info[iounjt]~
} else {
r ?
WO 94/07316 Pcr/us93/o8674 .

2~441~4 if niu.c IF DROP(ffq);
m i,~u~
error= ENOBUFS;
} else {
TR1 (TL1, ~%d on queue: ~, Ifq-~ifq len);
IF ENQUFIlF(i~q m);
(*nlu info[iounit].sen i~Jkl) (iounit);
rts:
splx(s);
TR3~rLl, ~vcoutput->%d, %d q %d d\n~, error, ifq->ifq len, ifq->ifq_drops);
return error;
}

int niu esr = o;
niu restart sen~s(unit) struct atmif *atp;
N (!niu esr) return;
atp = svc glob->svc pcH[unit].pc atmif;
while (atp~{
if (((struct ifnet *) atp->ati ac)->if snd.ifq len) (*niu info[unit].sendpktr(unit);~
atp = atp->ati next;
}

/*
* Name: n~
* Input: *ifp - pointer to network i,lt~,race to use. cmd * - cor"",and requeste I *data - data assoc~ Pci with the cullull~nd.
* Output: *data - data may be filleci In by certain cu"""~ncis.
* Return: 0 - no error. Error - Unix error code.
*

* Desc,i,~,llon. This is the network i"le,iace locti routine. An ifreq * structure must be used to access thls routine.
nil:s3'3ctl(ifp, cmd, data) register struct Hnet *ifp;
int cmd;
caddr t data;

W O 94J073162 ~. 4 ~ ~ 5 I PC~r/US93/08674 9~ .
if niu.c : `

lnt error = 0, i, s, svc timeoutO;
int Hunit= ffp->H unit, - extem Int atmarp timeol, atrnarp timeo2;
struct Hreq *Hr = (struct Hreq *) data;
struct Haddr *Ha = (struct Haddr *) data;
struct niu arpcom *ac = (struct niu arpwm *) Hp;
struct dblnfo *dbp;
struct mcaddr *mca;
struct atmH *atp;
TR2(TL3, ~aa%d(%x): n ~ entered\n~, Hunit, cmd);
switch (cmd) {
case SIOCSIFADDR:
/* set the Int~race ip address */
TRl~rL4, ~aa%d: iocti SlOCSlFADDR\n~, Hunit);
switch (ifa->ifa addr.sa family) {
#ifdef INi T
case AF INi-T:
niu a" co",s[ifunit].ac ipaddr =
IA SlN(ifa)->sin addr;
' ffp->H flags l= IFF UP;
break;
#endif default:
break;
break;
case SIOCSIFFLAGS:
/* set interface flags */
TR3(TL4, ~aa%d: iocti SlOCSlFFi~G (%d)flag=96d\n~, ifunit, ifp->if flags, ifr->Hr flags);
ifp->if flags = ifr->Hr flags;
H (ifp->H flags & IFF IJP) {
struct niu dev *niu;
niu = &niu info[NlU IFUNIT TO lOUNlT(i~>H unit)l;
H (niu-~type = = Nl~J TYPE~iU1~ {
setup rxbuf(nlu);

break;
case SIOCGIFFLAGS:
/* get l~ltt ~race flags */
TR2(TL4, ~aas6d: ~octi SIOCGIFFLAG flag=%d\n~, Hunit, Hp->H flags);
Hr->ifr flags =~fp->H flags;

W O 94/07316 PC~r/US93/08674 ~14~ 5ll ' if niu.c break;
case SIOCGETPORT:
/* get port address *t TR3(TL4, ~aa%d: iocti SlOCGi_TPORT port=%8x%~\nY, Hunit, atm glob->atmN[Kunit].ati port.aa iong[0], atm glob->atmN[Nunitl.ati~por~aa long[
Hr->Nr addr.sa family = AF CCITT;
bcopyT&atm grob->atmN[Nunit].ati port, ifr->ifr addr.sa data, skeofrstruct atm addr));
break;
case SIOCNIUDBUG:
/* set debug level for the entire niu device */
dbp = (struct db info *) Hr-> if r data;
niu debug = dbp->niu debug,~ /* network l,ltt:"ace */
niu trace = dbp->niu trace;
arp debug = dbp->arp debug; /* arp */
arp trace = dbp->arp trace;
drv~debug = dbp->drv debug; /* /dev/nlu */
drv trace = dbp->drv trace;
DB3(DL2, Uaa%d: iocti SlOCSNlUDBUG niu=%d %d\n ifunit, niu debug, niu trace);
DB3(Di 2, raa%d: iocti SIOCSNIUDBUG arp=%d %d\nY, ifunit, arp debug, arp trace);
DB3(Di 2, ~aa%d: locti SrOCSNlUDBUG dN=%d %d\n~, Nunit, drv debug, drv trace);
break;
case SIOCGIFADDR:
case SIOCGMACADDR:
/* get the i,l~t:tr~ce ip address */
TR1 (Ti 2, ~aa%d: iocti SlOCGlFADDR\n", Nunit);
bcopy(&niu ar~co,.,s[Nunit].ac atmif->ati rnac.aa byte[2], Ifr->Hr addr.sa data, 6);
break;
case SIOCSMACADDR:
/* set the i,lL~,~ace ip address */
TR1 (Ti 2, "aa%d: iocti SlOCSlFADDR\n~, Nunit);
bcopy(Nr->Nr addr.sa data, &niu ar~cor"s[Nunit].ac atmN->ati mac.aa byte[21, 6);
break;
case SIOCGMTIME01:
bcopy(&atmarp timeo1, &Nr->Nr rnetric, skeof(in~));
break;
case SIOCSMTIME01:
bcopy(&Hr->Nr metric, &atmarp timeo1, skeof(int));
break;
case SIOCGMTIME02:

~4~15~
W O 94/07316 PC~r/US93/08674 /o/
if niu.c , ~, bcopy(&atmarp timeo2, &ifr->ifr metric, ~keor(l"l));
break;
case SIOCSMTIME02:
bcopy(&ffr->Kr metric, &atmarp timeo2, sizeof(int));
break;
case SIOCTIMEOUT:
if ((atp = atm glob->atmlfl == 0) {
error= EN~IO;
break;
s = splnetO;
untimeout(svc timeout, atm glob->atmH[Hunit].ati pcK);
svc timeout(atm glob->atrniflifunit].ati pcif);
forT; atp < &atrn glob->atmiflatm glob->atmif usedl;
atp+ +) {
if (atp->ati state == ATS INACTIVE) continue;
} atm_~ "er(atp);
splx(s);
break;
case SIOCADDMULTI:
TR1(TL4, ~aa%d: iocti SlOCADDMULTl\n~, Hunit);
error = niu addmulti(ifp, ifr->ifr addr.sa data);
break;
case SIOCDELMULTI:
TR1(TL4, "aa%d: ioctl SlOCADDMULTl\n~, ifunit);
error = niu delmulti(ifp, ifr->ifr addr.sa data);
break;
case SIOCSPROMISC:
ifp->if flags^= IFF PROMISC;
p, i, l~r(~aa%d pr~" "iscuous %sabled\n~, if unit, if p-> if flags & IFF PROMISC ? ~en~: ~dis");
break;
case SIOCGSTATE:
/* get signaling vc state */
TR2(TL4, "aa%d: ioctl SIOCGSTATE state=%d\n~, ifunit, atm glob->atmiflifunit].ati pcif->pc slg->vcte state);
ifr->ifr metric=
atm glob->atmiflifunit].ati pcif->pc sig->vcte state;
break;
case SIOCSSTATE:
/* get signaling vc state */
TR2(TL4, ~aa%d: ~octi SIOCGSTATE state=%d\n~, ifunit, atm glob->atmiflifunit].ati pcif->pc sig->vcte state);
if (ifr->ifr metric < VCS INACTIVE
ifr->ifr metric > VCS ACTIVE) error -=ElNVAL;
else svc new state(atm glob->atmif[ifunitl.ati pcK->pc sig, WO 94/07316 PCI'/US93/08674 ~ .
/~
if_niu.c Kr->ifr metric);
break;
default:
DB2(Di, "aa96d: iocU bad command=96x\n~, ifunit, cmd);
error= EINVAL;
return (error);
}

/*
* Find a multicast entry ~n the multicast filter for atm lan, atp.
/
struct mcaddr *
niu findmulti(atp, mac) struct atmif *atp;
u char *mac;
{

int j;
for (i = 0; i < atp->ati num mcasts; I+ +) if (bcmp(atp->ati .ncadd.~[i].mc enaddr, mac, 6) == 0) return &atp->ati mcaddrs[i];
return 0;
/*
* Add a multicast address to multicast filter for atm lan, atp.
niu addmulti(ifp, mac) struct if net *ifp;
u char *mac;
int i, s, error;
struct aate *at;
struct mcaddr *mc;
struct atmif *atp = ((struct n~u arpcom *) ifp)->ac atmif;
if ((mac[0l & ox1) == 0) return EINVAL; /* not a multicast address */
mc = niu findmulti(atp, mac);
s = splimpO;
if (mc) {
if (mc->mc count ~ MCCOUNTMA~ {
mc->mc count++;
splx(s);
return 0;
} else {
splx(s);
return ENOSPC;

WO 94/07316 PCr/US93/08674 21441~i4 if niu.c }

K (atp->ati num mcasts == MCADDRMA~q {
- splx(s);
retum ENOSPC;
}

mc= &atp-~ati ",caddl~latp-~ati num mcastsl;
mc-~mc count= 1;
bcopy(mac, mc->mc enaddr, 6);
at = mc->mc at = atm find at(atp, mac);
K (at == 0) {
splx(s);
retum ENOSPC;
at->aate flags 1= ATF MULTI;
atp->ati num mcasts++;
splx(s);
return 0;

/
* Delete a multicast address from multicast filter for atm lan, atp.
niu delmulti(Hp, mac) struct Hnet *ifp;
u char *mac;
struct mcaddr *mc;
int i, s;
struct aate *at-struct atmif *atp = ((struct niu arpcom *) Hp)->ac atmH;

mc = niu findmulti(atp, mac);
H (mc =- 0) return ENXIO;
s = splimp0;
K (-mc->mc count > 0) {
spix(s);
retum 0;
} else K (at = mc->mc at) {
ASSERT(at->aate flags & ATF MULTI);
at->aate flags &- ~ATF MULTI;
atm aate free(at);
bcopy(&atp->ati ",cadu~ [-atp->ati num mcasts], mc, ~keo~(t~llc));
,~ splx(s);.
return 0;

WO 94/07316 PCI'/US93/08674 -2 1 ~ /~
if niu.c /*
* go steai an ~ll ,el,.~L:, low order 2 bytes and append it two * Adaptive's IEEE prefix.
*/
unsigned Int def enaddr[21 = {nxno8oh~eo~ Ox00010000};
nlu get enaddr(unit, enaddr) u Int unit;
u char ~andd i~, {

struct ifnet *ifp;
extern struct ifnet *ifnet;
bcopy(def enaddr, enaddr, 6);
for (ifp = ~net; Hp; ifp = ifp->if next) if (ifp->N mtu == 1500) {
enaddr 3 = (((struct niu arpcom *) ifp)->ac enaddr[3] & Ox1fl 1 OxeO;
enaddr 4 = ((struct nlu arpcom *) Hp)->ac enaddr[4];
enaddr.5 = ((struct niu arpcom *) ifp)->ac enaddr[5];
} break;
enaddr[O] = (u char) unit << 1;
}

/*
* This routine just looks up the input vcl and ii ,l~al.:l,es the frame * to the ap;J,o~ nput routine based upon vci. Signaling and * raw user access does not necessa~ily use 802.6 framing.
*/
Int svc_send releases= 1;
deliver packet(unit, mO, vci) int unit;
struct mbuf *mO;
u short vci;
{

struct vcte *vp;
struct pcif *pc;
int s;
int plen;
plen = m ien(mO);
aal trace m(mO, plen, 1, vci);
s = spllmpO;
pc= &svc glob-~svc pcif[unit];
if (pc->pc rdw vp) {
pc->pc raw vp->vcte lI~ ++;
pvc input(pc->pc raw~vp, mO);
} else7f (vp = ivpcl to vcte(pc, vci)) {
if (VCS DATA IND OK 8 VCS TO VMASK(vp->vcte state)) {

WO 94/07316 2 1 9~ 1 1 !; ~I PCI/US93/08674 if_niu.c ASSERT(\/AUD ULP(vp->vcte ulp));
vp-~vcte Ipackets++;
(*vp->vcte ulp->ulp data) (vp, mo);
} else m rlt:e",(,10);
} else~ (svc send releases 8& pc->pc sig) {
struct release *pdu;
m freem(mO);
p~u = (struct release *) atm alloc ms~O;
pdu-~lmi proto = LMil PROTOCOL;
pdu->lmi pdu type=TDU INVALiD PDU;
pdu-~lmi cref type = LMI CREFrYFE PVC;
pdu->lmi cref vaiue = vci;
Ll~fil SET ELEMENT(&pdu->lmi cause, LMI RELi-ASE CAUSE, ~ICI IINACCEPTABLE);
svc xdu~pc, O, pdu, s~eof *pciu);
}
} splx(s);

/*
* niu_snitifyO makes a copy of mO, converts the 802.6/SNAP header * into an ethemet header and calls snit intrO.
*/
struct nit if niu nit;
u short enet hdr[7];
niu snitify 8026(ifp, m, hlen, promisc) struct ifnet *Hp;
struct mbuf *m;

int adj;
u char *sp; /* start of de~li"~lion adr in 802.6 * header */
ASSERT(hlen >= 20);
H (m->m len < hlen + 3) retum; /* not enough for llc */
sp = mtodrm, u char *);
bcopy(&sp 2], enet hdr, 6);
bcopy(&sp 2 + 8~j, &enet hdr[3j, 6);
ff (sp[hlen] == (u char) Oxaa) {
bcopy(&sp[hlen + 6], &enet hdr[6], 2);
adj = hlen + 8;
} else {
bcopy(&sp[hlen], &enet hdr[6], 2);
adJ = hlen + 3;
H (m-~m ien c adj) WO 94/073 1 6 PCI'/ US93/08674 2144154 /i~niu.c retum;
m->m ien-= adJ;
m->m off += adJ;
niu nit.n~ header = (caddr t) enet hdr;
niu nH.nif hdrien = 14;
nlu nit.nif bodyien = m ien(m)-14;
niu~nit.nif~promisc= p~UI~;Sc, snit intr(ifp, m, &niu nit);
m->m len += adJ;
m->m off-= adJ;
}

int dump len = 64;
int dump iimit = O;
dump frame(s, dp, words) char *s;
int *dp;
int words;
if (dump_iimlt == O) return;
prjnff(u%s~l S);
if (words > dump iimit) words = dump iimit;
while (words-) prinff("96x ~, *dp+ +);
} prinff( \n );

int dumpbuf[64];
int dumplen = 64;
dump chain(s, m) char *s;
struct mbuf *m;
{
int left= m ien(m);

if (ieft > dumplen) left = dumplen;
m copydat(m, (char *) dumpbuf, left);
le~ = (left + 3) / 4;
dump frame(s, dumpbuf, left);
}

m len(m) struct mbuf *m;
{

int len;

214 ~1 5 ~ PC~r/US93/0867~

~o7 if niu.c for (len = 0; m; m = m-~m next) len += m-~m ien;
retum len;
}
atm arpiocti(Hunit, cmd, data) int cmd;
caddr t data;
struct arpreq *ar = (struct arpreq *) data;
struct aate *at;
int s, error = o;
if (ar->arp pa.sa family l= AF UNSPEC
ar->arp ha.sa_family l= AF CCITT) retum (EAFNOSUPPORT);

at - atm arptab_iook(&atm glob-~atmif[ifunit~, ar->arp pa.sa data~;
if (at == NULi ) error= ENXiO;
else if (ar->arp pa.sa data[0] & 0xo1) error= EIN\rAL;
else if (cmd == SIOCDARP) atm aate free(at);
splx(s~
return error;
}

calc mlen(m) struct mbuf *m;
int len = 0;
TR0~rL2, ~calc mlen: called\n~);
while (m) {
len += m->m ien;
m = m->m next;
DB1(DL3, ~caic mlen: len=Ox%x\n~, len);
retum (ien);
}

m copydat(m, buf, len) struct mbuf *m;
char *buf;
int len;

~oOo 2 t 4 4 1 5 ~ if niu.c int J;
while (len && m) {
j = len;
if 1- > m-~m len) = m->mlen;
if J){
bcopy(mtod(m, caddr t), buf, J); O
buf += J;
len-= J;
}

m = m->m next;
}

return len;
}

aal trace m(m, tlen, in, vci) struct mbuf *m;
{

int s;
if (!aal trace enable) retum;
atm trace buf(m, m copydat, IF TRACE LOG, tien, in, vci);
spLx~s);
}

WO 94/07316 2 1 ~ ~ 1 5 4 Pcr/US93/08674 -o9 if niu.h ~i `

/* if nlu.h * COPYRlGi-iT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
/* static char sccsid[] = "@(#) if niu.h 1.12~?(#)~; */
* The aai lul~,tdce is Implemented as mes~ges send (a)sy"chlol1ously * b~lw~,en the MAC and aal layers. The aal parms structure p,t:ceecis * frames transmitted and received. It Is the co", '~e Interface * b hr,_en the aai layer and the aal user. Rather than define some * VC pdldlllt~lel~ at circuit setup time and pass other per frame * pandi"~ with each frame, all pardr"~ are passed with each * frame. Thus, at the loss of some pe,ru"~ance, the Inl~tdce * betwen the H/W NIU (and 960 OS) and the host is simplifiec.
* To do: Average rate Ill~l~ri,,g pa-d",el~ will be added when we figure * out how to use them. frame level CRC should be .spec;,ied but * current chlps have a mode bit for CRC.
*/
struct aal parms ~
- vpci t ap vpci;/* vpci to be operated upon */
u short ap mid; /* mid to use with frame */
u short ap ien; /* packet length (excluding aai parms * and */
/* pad bytes if MLP CRC SMDS) */
u short ap rate-/* burst rate for frame divided by * 1024 *,7 u char ap orderq; /* Identifies an ordered send * queue. Frames */
/* with the same orderq may not be interieaved. */
/* MLP UNORDERED i" iical~s no It~ ions */
u char ap fia~s; /* MLP CRC ~ooc */
};
/* ap crc32 values */
#define MU CRC NONE 0 #define MU CRC ADAPTIVE 1 #define MU CRC SMDS 2 #deflne MLP RAVV CELL 4 #deflne MU ENAI~i E XON XOFF 8 /* enable xon/xoff higher * layer */
#define MU LOOP VCI 0x10 /* loop rcv frames at 960 */
/* ap rate value to specify maximum link rate */
#define MLP MAX RATE (~0) /* ail one's */
/* ap orderq value i~frame has no ordering constraints */
#define MU UNORDt~tu 0 /
* ~ luo~trllt0 soc~ used for raw aal access with AF DLi.

WO 94/07316 PCr/US93/08674 214 l~ o if niu.h * saal vcte must r~w~nce a vaiid vcte.
/
struct soc~ lr aai {
u short saal family;
u short saal pad2;
struct vcte *saai~vcte;
char saal pad6~6];
};

struct niu desc {
u char status;
u char niual-u short reserved;
u Int pkt addr;
u short size;
u short vci;
u int chain ptr;
};
/* used for SIOCNIUDBUG iocti */
struct db info {
char niu debug-char niu trace;
char arp debug;
char arp trace;
char drv debug;
char drv trace;
};
/* MTU size */
#define MMTU 9188 /* receive control registger */
#define RCNTL REG 0 #define RCNTL IDLi- INTR 0x80 /* rxfill interrupt */
#define RCNTL-FILL1NTR 0x40 /* rx idle interrupt */
#define RCNTL PASS -iDLE 0x04 /* go through idle on every * ce~l */
#define RCNTL STOi' IDi~ E OX02 /* stop on Wle */
#define RCNTL RESi~ 0x01 /* reset rx fifo, abort cell, * spill mocie */
#define RCNTL MASK 0xc7 /* bits 3-5 unused */
/* receive status register 1 */
#define RSTAT1 REG
#define RSTAT1 LiGHT 0x80 /* rxfiberlight present *~
#define RSTAT1 FIFO HALF 0x40 /* rxffo halfflag */
#define RSTAT1-FIFO-FULL 0x20 /* rx ffo full flag */
#define RSTAT1 FIFO EMi~ OX20 /* rxfifo emptyflag */

WO 94/07316 2 1 4 4 1 5 4 Pcr/us93/o8674 , . . .
", if niu.h #define RSTAT1 VIOLATION 0x04 /* rx violation */
#define RSTAT1 MASK 0xec /* bits 01 4 unused */
/* receive status register 2 */
#define RSTAT2 REG 2 #define RSTAT2 IDi- E 0x80 /* rx is Wle */
#define RSTAT2-FIFO OVR 0x40 t* Kffo overflow*/
#defineRSTAT2 CMD OVR Ox20 /* rxccr".,al,doverflow*/
#define RSTAT2-CMD-RECV 0x10 /* rx cor ",~nd received */
#define RSTAT2-COM-MAND 0x0f /* rx co"""and, 4 bits */
#define RSTAT2 INTR MASK 0xdO /* rx Interrupt mask */
/* transmit control register */
#define TCNTL REG 3 #define TCNTL RESET 0x80 /* tx reset */
#define TCNTL LOAD 0x40 /* load tx fifo */
#define TCNTL SOC ENBL 0x20 /* start of cell enable */
#define TCNTL ENAE~LE 0x10 /* enable send from fifo */
#define TCNTL COMMAND 0x0f /* tx collllllal1d */
/* transmit status register */
#define TSTAT REG 4 #define TSTAT FIFO FULL 0x80 /* tx ffo full */
#define TSTAT FIFO HALF 0x40 /* tx ffo half */
#define TSTAT FIFO EMPTY Ox20 /* tx fifo empty */
#define TSTAT MASR OxeO /* bits 0-4 unused */
#define MAX INTR TIME 200 /* dma cor,lr. ~r control/status */
#define DMAC INT PEND ny~nooooool /* interrupt pending */
#define DMAC ERR PEND OX00000002 /* error pending */
#define DMAC DRArNlNG nY~nooooooc /* drain~ng D cache */
#define DMAC INT EN r)yoooooo1o /* interrupt enable */
#define DMAC FLUSH oYnooooo7o /* flush buffer */
#define DMAC SLAVE ERR 0x00000040 /* slave error */
#define DMAC RESET nynooooogo /* reset DMA */
#define DMAC-WRITE 0x00000100 /* 1 = memory write; 0 =
* memory read */
#define DMAC EN DMA nYnooon~no /* enable drna */
#define DMAC EN CNT oY~ oon~noo /* enable counter*/
#define DMAC TC 0X00004000 /* terminai count */
#define DMAC-Ai E AS 0x00100000 /* 1 = addr latch enb; 0 * = addr strobe */
#define DMAC i- ANCE ERR oYnn~ooooo /* E channel error */
#define DMAC FASTER OX00400000 /* fast access for D
* channel */
#define DMAC TCI DIS nYno80000o /* TC interrupt disable */
#define DMAC EN NEXT 0x01000000 /* enable next */
#define DMAC DMA ON oY~n~nooooo /* DMA on */
"

W O 94/07316 PC~r/US93/08674 2 1 ~
if niu.h 7q #defineDMAC A LOADED n~ ~00000 t* address loaded */
#define DMAC NA LOADED 0~8000000 /* next address loaded */
*define DMAC DE~iD QY~000000 /* device id */
#define DMACINTRiUASK n~oooooo3 /*DMAC interrupt * pendl~ng mask */
/* dma address */
#define DMAC ADDR REG 6 /* dma next address */
#define DMAC ADDRNXT REG 7 /* dma count */
#define DMAC COUNT REG 8 /* dma next count */
#define DMAC CNTNXT REG 9 #define SW NUM_SWREGS 10/* number of ,e~;st~r~ on sw * niu */
#define NUM SWREGS 3 /* number of .~g;~ter~ on sw * niu */
#define NUM SWINTR 1 /* number of interrupts on sw * niu */
struct niu addr reg {
u char ~*rcnti reg; /* receive control register */
u~char *rstat1 reg; /* receive status 1 register */
u char *rstat2 reg; /* receive status 2 register */
u char *tcnti reg; /* transmit control register */
u char *tstat~reg; /* transmit status register */
};
struct niu value reg {
u char rcntl reg; /* receive control register */
u_char rstat1 reg; /* receivestatus 1 register*/
u char rstat2 reg; /* receive status 2 register */
u char tcnti reg; /* transmit control register */
u_char tstat reg; /* transmit status reglster */
};
struct hw niu reg {
u long *dma reg;/* LSI dma status reglster */
u short *attn reg; /* niu all~n~iol, register */
u long *base reg; /* niu base register */
u short *intr reg; /* niu interrupt ach vuriedge * register */
u short *lock reg; /* niu dma lockout register */
u iong dma vaiue; /* local copy of dma status W O 94/07316 2 ~ ~ ~ 1 5 4 PC~r/US93/08674 3 .
if niu.h * register */
u short attn vaiue; /* locai copy of niu - * dllt~ ioll register */
- u long base vaiue; /* local copy of niu base * register */
}.
struct dmac addr reg {
u long ~ *status reg; /~ status control reglster */
u long *addr reg; /*address register*/
u~ong *next address reg; /* next address register */
u~iong *count reg; /* count reglster */
u iong *next count reg; /* next count register */
~;
~define NUM DESC 1 /* up to 1 desc-,t~lul:i In * chain */
typedef struct {
caddr t dma addr;
int size;
} DMA DESC BUF;
struct dmac value reg {
u long status reg; /* status control register */
u iong addr reg; /* address register */
u iong next address reg; /* next address register */
u long count reg; /* count register */
u iong next count reg; /* next count register */
};
struct niu stats {
u long ip opkts; /* number tx ip packets */
u long Ip Ipkts; /* number rx ip packets */
u long arp opkts; /* number tx ip packets */
u iong arp ipkts; /* number rx ip packets */
u long drv opkts; /* number tx driver j~ackets */
u iong drv~ipkts; /* number rx driver packets */
u long crc errors; /* totai number crc errors */
u iong errors; /* totai number misc errors */
u iong ailocd failed; /* number of ailoc desc * failures */
u iong fi"ddesc failed; /* number of ",;~.. "~lcl,ed * tags */ ~
};
/* packet dilt: ;tion */
#define NIU RECEIVE O /* host n:ceivl,~g packets * from niu */
#define NIU TRANSMIT 1 /* host trasmi~ting packets * to niu */

WO 94/07316 ~ PCr/US93/08674 ~1441~4 "4 ~
if_niu.h typedef stnuct {
int In use;
Int cmd tag;
struct mbuf *rn;
int num desc;
caddr t desc addr;
DMA DESC BUF *desc ptr;
caddr t data addr;
} DMA DE~C;
#define NUM DMA DESC 11 #define COMMAND SIZE 16 #define NO COMMAND 0 #define RESET CMD
#define STATUS CMD 2 #define CLR STATS CMD 3 #define RX DATA CMD 4 #define TX DATA CMD 5 #define CLR INTi~ CMD 6 #define RESET Q CMD 7 #define WORK AROUND CMD 8 #define BOARD ID CMD 9 #define CMD INTR OFF 0x00 #define CMD INTR ON 0x01 #define CMD CRC MASK 0x06 /* frame level crc */
#define CMD CRC ADAPTIVE 0x02 #define CMD CRC SMDS 0x04 #define CMD CRC NONE 0x00 #define CMD ML MASK 0x18 #define CMD ML-4 0x00 /* default is aal4 */
#define CMD ML5 0x08 /* not yet i~., '-- ..enled */
#define CMD ML RAW 0x18 /* send raw cell aia s/w niu */
#define CMD ENABLE XON XOFF 0x20 /* enable xon/xoff */
#define CMD LOOP VCI 0x40 /* loop rcvframesat960 */
typedef struct {
u char param[COMMiAND SIZE-4];
u short tag;
u char flags;
u char cor--,~l-J, COMMAND;
typedef struct {
u char param[COMMAND SIZE-8];
u int board id;
u short tag;
u char flags;

WO 94/07316 ~ PCI'/US93/08674 -~/5 if niu.h "
u char cor"",alld, } BID CMD;
typedef struct {
caddr t dma addr;
u short vci;
u short mid;
u short ske;
u char order q;
u char rate q;
u short tag;
u char flags;
u char co"""and;
} RX CMD;
typedef struct {
caddr t dma addr;
u short vci;
u short mid u short size, u char order q;
u char rate q;
u short tag-u char flags;
u char co,-""and, } TX CMD;
#define CMD Q SIZE NUM DMA DESC
#define STAR~ CMD Q( q ) (&(~q)->cmd q[ 0 ])) #define CUR CMD Q ' q ) (&((q)->cmd_q[ (q)->cmd elem 1)) #define END CMD Q q ) (&((q)->cmd q[ CMD Q S7ZE -1 ])) #define NEXT_CMD_~ eie )m ) if (+ + (elem~ > = CMD_Q_SIZE)\

typedef struct {
int cmd elem;
COMMAND *cmd q;
CMD Q;
typedef struct {
u char crc err;
u char par~y err;
u char buf ovr;
u char buf avail;
u char pkt drop;
u char celrdrop;
} HWNIU STATS;
typedef struct {
u short rx packets;

W O 94/07316 . Pc~r/US93/08674 2~ 15~
/~6 if niu.h - ~7~
u short tx packets;
HWNIU STATS stats;
u ehar reserved[6];
} NIU STATUS;
typedef struet {
eaddr t emd start; t* eo"",.and q start */
eaddr t emd~end;/~ c~n""and q end */
caddr t done start; /* eompleted q start */
caddr t done~end; /* cor, - - q end */
caddr t status_start; /* status location */
} HOST BASE;
#define MAP CMD Q 0 #define MAP DON-E Q
#define MAPSTATU-S 2 #define MAP BASE 3 typedef struct {
eaddr t base dma; /* host base dma address */
caddr t status dma; /* status dma address */
caddr t cmd_dma;/* cmd q dma address */
caddr t done dma; /* done q dma address.*/
} DMA ADDR;
/* board ids */
#define NIU REV2 0 ;~define NIU Ri-V3 #define PNI~ Ri-V12 #define PNIU Ri-V2 3 #define PNIU REV3 4 struct niu dev {
u char type;
u short tag; /* tag for each con""and */
CiMD Q emd q- /* co"""and q */
CMD Q done q; /* co", ~e~ q */
NIU ~TATUS status, /* hw niu status location */
HO~T BASE base; /* host/niu io base structure */
DMA ADDR dma addr; /* mapped dma address */
int ~ priority; /~ interrupt priority */
struet hw niu reg niu reg; /* address of ~ V~r~ on * niu board */
struct niu stats stats; /* niu ~ L~ 5 */
DMA DE~C desc[CMD Q SIZE]; /* desc~ o, pool */
Int ~ intr timeout; /* rnterrupt timeout counter */
struct niu addr~reg niu addr; /* address of r~g;~.t~, on * niu board *7 struct niu value reg niu vaiue; /* eo,llerlls of r~ , on * niu board *~
struct dmac addr reg dmac addr; /* address of ~e:g;~tt:~ on * ~i4853A SBus culll-.'ler */

W O 94/07316 2 1 ~ 4 1 ~ 4 PC~r/US93/08674 ~ , ;
~/7 ~ ~;
if niu.h struct dmac value reg dmac value; /* co~ r~l~ of It~ t~
* on i 64853A SBus * conLr~'le */
Int (~sen i~hl) O; /* hw specKic routlneto * send queued pkts */
Int (*reset) O; /* hwspecKic routineto * reset hw */
#define NIU TYPE SW 1 ~define NIU TYPE HW 2 u short dl. ~ion, /* receive or transmit * packets */
int board Id; /* niu board revision */
Int intr state; /* Is in Interrupt state */
Int post rxbuf; /* count of rx buifers to be * posted */
struct Hqueue sendq;
Int ,.,acad i~ [21;
};
extern struct niu dev niu Info[];
extern Int celi flag; /* set for l,~",;ss;on of raw ~3 byte * cells */
#define NIU IFUNIT TO lOUNlT(ifunit) (atm glob->atmif[ifunit].ati_pcif->pc num) WO 94/07316 ` PCI/US93/08674 .
211415 l Im.c /* Im.c * COPYRIGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
*

AAAAI.AAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtNLlA~AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
#ifdef CERNEL
#include"ipc def.h~
#include "net def.h~
#include <global def.h>
#include ~driver.h>
#undef Im init #else /* ifndef CERNEL */
#include <stdint.h>
#include <global def.h>
#Include <ITC H.h>
#include <driver.h>
#include <RT Kh>
#include <timer.h>
#include <RT def.h>
#include <enet if.h>
#include <net def.h>
#define ERRLOG printdbg #define printf printdbg #endif /* ifdef CERNEL */

#include "unipdu.h"
#include ~nnipdus.h"
#include~altask gl.h~
#include~sigtask gl.h~
#include~svctasi< gl.h~
#include"svc H.h~
#include"snrnp incl.h~
#include ~ML H h~
#include"wdb H.h~
#include Yq.h~
#include ~bits.h~
#include "Im.hN
Im tcb t *Im InitO;

WO 94/07316 2 1 ~ ~ t 5 ~ Pcr/US93/08674 Im.c .
~1-#Hdef CERNEL
#include ~stdio.h>
main(arge, argv, environ) int arge;
ehar *argv[];
ehar **environ[];
tlNT32 generie;
tlNT32 i"~tdnee;
tlNT32 status;
tUlNT8 test mode;
generic = TID Wi;
instance = O;
if ((status = SetTid(generic, instance)) 1- RT SUCCESS) {
~c.li"Lr( ""; SetTid Failed\n~);
} else ~
Im mainO;

#endif /* Hdef CERNEL */
Im mainO
Im tcb t *tcb struct flmerBlock *tmr blk;
tUlNT32 *msg;
tlNT32 delay;
tUlNT32 timerid;
tUlNT32 lill,erc~,y, tcb = Im initO;
H (tcb =- NUi L) {
p~i"Lr( li". init failed");
retum;
tmr blk = tcb->tmr blk;
timerid = tcb->timerld;
IT",erd,y = tcb->linl~laly~
while (TRUE) {
delay= O;
while (delay <= O) {
delay = TimerCheck(l"" blk, &timerid, ~&lilll~ldly);
H (delay <= O) {
Im srvc timer(2);
RTC TimerSet(tmr blk, (GetTimeO ~ (STGRAN)), timerid, lilllt:l~ly);

WO 94/07316 PCI'/US93/08674 , /~
214415ll Imc msg = (tUlNT32 *) ReqMsg(LNi EX MSK, delay);
If (msg l= NULL) {
Im srvc -lsg(lll~g);
free(ms~

} }
Im srvc timer(delay) -tUlNT32 delay;
{

SETUP TCB;

Im srvc msg(msg) tlTC HEADER *msg;
{

int ret;
int Im crt cfgO;
SETUP TCB;
ret= RT SUCCESS;
pril ,Lt( ~ srvc msg, MsgType = %d\r\n", msg-> MsgType);
switch (msg->MsgType) {
case TA ML IND RECEIVE:
Im srvc aal msg(msg);
break;
case U DTIND:
Im srvc svc msg(msg);
break;
case SNMPA MGMT GET:
Im srvc mgmt geL(Illsg);
break;
case SNMPA MGMT VALiDATE:
Im srvc mgmt vardate(msg);
break;
case SNMPA MGMT COMMIT:
Im srvc rngmt commit(msg);
break;
case SNMPA MGMT GETNEXT:
Im srvc mgmt g~L~ t(~sg);
break;
case SNMPA CHECKiN MSG:
SendProxyCheckin(hlHW GetCardTypeO, W O 94/07316 2 1 4 ~ 1 5 ~ PC~r/US93/08674 /~?/
Im.c MHW l~etQlotlcl0);
break;
default:
if ((msg->MsgType >= MSG WDB BASE) &&
(msg->MsgType ~= MSG WDi3 TOP)) {
wdb process msg(lm crt cfg, msg);
} else ~
ret = !RT SUCCESS;
goto err exit;
break;
return (ret);
err exit:
return (ret);

Im srvc aal msg(msg) ~AAL TA~ND RX *msg;
{
Int ret;
Im alan cfg enq t *aal msg;
tUlNT32 pvci;
tUlNT32 vci;
aal msg = (Im alan cfg en~_t *) msg->i~cBuifer;
ret - RT SUCCESS, vci = ((Im atm_hdr t *) & (msg->RxATM Hdr))->vci;
pvci = VCT TO PVClm(vci);
if (aal msg->lmi hdr.lh pciu type l= NN PDU STATUS ENQ
aarmsg->lmrhdr.lh proto l= NNI Pi~OTO~OL
pvcl l= NNI NAC VCI) {
ret= IRT S~CCESS;
goto err exit;
}

switch (aal msg->enq.elem type) {
case ALAN CFG ENQ:
ret = Irn~srvc~alan cfg enq(msg);
break;
case i~l CONFIG ENQ:
ret = rm srvc es cfg enq(msg);
break;
default:
goto err exit;
break;
return (ret);

WO 94/07316 PCr/US93/08674 2 ~ 4 ~
Imc err exit:
return (ret);

Im srvc alan cfq enq(msq) tAAL TA iND RX *msg;
{

Int ret;
Im alan cfg enq t *alan enq;
tAGANCFG ENQ *enq;
tALANCFG RESP *resp;
tATMADDR paddrs[MAX PORTS PER SLOT];
tUlNT32 in srvc;
tUlNT32 irl srvc mask;
int i;
Int max port;
Im port addr t tst;
Im port t *port;
Im mac t *mac;
qlink t *link;
Im rnac vian t *mv;
tUrNT32 tx vci;
tUlNT32 rx vcl;
tUlNT8 rx shelf;
tUlNT8 rx slot;
tUlNT8 rx port;
Im prefix t prefix;
Im atm hdr t atm hdr;
SETUP TCi3;
ret= RT SUCCESS;
alan enq = (Im alan cfg enq t *) msg->Rx.Buffer;
enq = &alan enq->enq;
in srvc = 0;
in srvc mask = n~ooooooo;
max port = MAX PORTS PER SLOT > enq->num ports ?
enq-~num ports: MAX PORTS PER SLOT;
i l\fi INIT PORT ADDR(&tst, tcb->rny node, tcb->my shelf, enq->siotid, 0);
for~i = 0; i < max port; i++) {
tst.aa iannum = 0;
tst.aa port = i;
port - FIND PORT(tci~>port q, &tst);
if (port l= N~i L) {
mac= port->mac;
if (IIS EMPTY Q(port->pv q)) {
paddrs[i] - tst;
} in_srvc l= in_srvc_mask;

WO 94/07316 2 ~ 4 ~ 1 ~ 4 Pcr/US93/o8674 ., . ~ .-; .
Im.c if (mac l= NULL && IIS EMPTY Q(mac->mv q)) {
link= HEAD Q(mac->mv q), mv = (Im mac vian t *) link->data;
tst.aa lannum - mv->mlid;
paddrs[i] = tst;
in srvc l= in srvc mask;
}
in srvc mask >>= 1;

atm hdr = *((im atm hdr t *) & msg->RxATM Hdr);
prefrx = *((lm prefix t *) &- msg->RxPrefk);
rx vci = atm fidrvci, tx vci = (rx v-ci & (~SIG PVCI MASiO I PVCI TO VClm(NNI SIG VCI);
rx shelf = \~CI TO SHELFm(rx vci);
rx slot = VCI To-~LoTm(rx vci);
rx~port = VCrTO PORTm(rx vci);
BUILD ATM_HDR(&atm hdr, tx vcl);
- BUILD UCAST PREFIXr&prefk, rx shelf, rx slot, rx port);
Im send alan cfg(prefix, atm hdr, enq->slotld, in srvc, max port, paddrs);
return (ret);
err exit:
return (ret);

Im srvc es cfg enq(msg) { tAAL_TA_lNi5_RX *msg;
int ret;
Im es_cfg enq t *es enq;
tCFGi_LEi~A *enq, Im mac t *mac;
Im~port t *port;
tUrNT32 rx vcl;
tUlNT8 rx shelf;
tUlNT8 rx~slot;
tUlNT8 rx~port;
tUli~T32 tx vci;
Im prefk t prefk;
Im atm hdr t atm hdr;
Im mac addr t *mac addr;
Im port~addr t port addr;
Im~es cfg resp t *resp;
Int resp len;
int l; ~
Si_TUP TCB;
., i WO 94/07316 ' PCI/US93/08674 ~.
2144~ 5ll Im.c ret= RT SUCCESS;
es enq - (im es cfg enq t *) msg->R~Buffer;
enq = &es enq->enq;
mac addr~S &enq->af my add~ess, atm hdr = *((im atm hdr t *) & msg-~RxATM Hdr);
prefK = *((lm prefK t *) &- msg-~nxPIer~); ~
rx vcl = atm hdr.vci, tx vci = (rx vci & (~SIG PVCI MAS19) I PVCI TO VClm(NNI SIG VCI);
rx~shelf = \TCI TO SHEI~m(rx vci);
rx slot = VCI TO SLOTm(rx vci);
rx port = VCrTO PORTm(rx vci);
LM INIT PORT ADDR(&port addr, tcb->my node, rx shelf, rx slot, rx port);
port = FIND PORT(tcb->port q, &port addr);
mac = FIND MAC(tcb->mac q, mac addr);
if (mac == NULL) {
mac = add mac(mac addr);
if (port != NUi L) {
atch mac port(mac, port);
} Im_dUP_POrt_dflts(port, mac);
if (port != NULL && (port->mac != mac 1 I mac->port != port)) {
free mac port(port->mac, port);
atch mac port(mac, port);
resp = Im build es cfg resp(mac, enq, &resp len);
If (resp =- NULI) ~
ret= !RT SUCCESS;
goto err exit;
}
BUILD ATM HDR(&atm hdr, tx vci);
BUILD UCA-ST PREFlXr&prefK, rx shelf, rx slot, rx port);
ret = Im send es cfg resp(prefK, atm hdr, resp, resp len);
return (ret);
err exit:
retum (ret);

Im_srvc svc msg(msg) tAALl~SR~iSG *msg;
{

tLMlHDR *Imi hdr;
tSETUP *setup;

., W O 94/07316 2 1 ~ 4 PC~r/US93/08674 Im.c e7-lmi hdr = (tLMilHDR *) ~ msg-~U i'DU;
switch (imi hdr->lh pdu type) {
case SDU SETUP rND:
Im srvc svc setup ind(msg);
break;
case SDU SETUP COMP:
break;
case SDU RELEASE IND:
Im srvc svc rel ind(msçi);
break;
default:
break;
}

Im srvc svc rei ind(msg) struct svclf *msg;

Im srvc svc setup ind(msg) struct svcif *msg;
struct svcif *resp;
tLMlHDR *Imi hdr;
tREL REQ *rel~
int ~ resp len;
int ret;~
Im mac t *mac;
Im~port~t *port;
Im vian t *vian;
Im~mac~vian t *mv;
Im mlid t mlid-tSETUP *rx setup;
tSETUP *tx setup;
Im port addr t port addr;
Im vc addr t vc addr;
Im~vc~t ~ *vc; ~
tU~iT8 *vpci;
SETUP TCB;
ret = RT SUCCESS;
resp len = SVCIF PDU OFFSET + skeof(*tx setup) +
sizeof(struct Imi parm) resp = (struct svcif-*) ReqMsgMemZero(resp len);
if (resp = = NULL) {
ret= IRT SUCCESS;
goto err exit;

W O 94/07316 PC~r/US93/08674 21~15~ Imc rx setup = (tSETUP *) & msg-~lmi hdr;
tx setup = (tSETUP *) & resp-~lmi hdr;
*tx setup = *rx setup;
Imrhdr = (tLi~AlRDR *) & tx setup-~lmi hdr;
Imrhdr->lh pdu type = S~U SETUP RESP;
port addr- rx setup-~lmi ca~ler;
mlidr= port addr.aa lannum;
port addr.aa lannum = O;
port- FlND~PORT(tcb-~port q &port addr);
H (port == NUi L) ~
ret= IRT SUCCESS;
goto err exit;
mac= port->mac;
if (mac == NULL) {
ret= IRT SUCCESS;
goto err exit;
mv= FIND MLlD(mac->mv_q mlid);
H (mv == NULi ) {
ret= IRT SUCCESS;
goto err exit;
vlan = mv->vian;
if (vian == NULL) {
ret= IRT SUCCESS;
goto err exit;
i M INIT VC ADDR(&vc addr vlan->vian id &rx setup->lmi callee);
vc- FI~D ~C(vian->vc q &vc addr);
(vc == N-ULL) {
vc = add vc(&vc addr);
if (vc == NULL) {
ret= !RT SUCCESS-} goto err_exit;
vc-~ref cnt++;
vpci = TtUlNTS *) tx setup + skeof(*tx setup);
LMI ADD ELEMENT~vpci LMI OVPCI vc-~bid);
Iml hdr-~lh cref type ~ MI C~t~ulkt~;llON MASK;
ret - Im send svc "l~g(r~. resp len);
return (ret);

err exit:
~ (resp != NULL) {

wo 94/07316 2 1 ~ ~ 1 5 ~ PCr/US93/08674 Im.c Imi hdr->lh cref type l= LMI CREFDIRECTION MASK;
Im send svc rel req(lmi hdr,TNVALlD STATE);
free(resp~; ~ ~
return (ret);

}

WO 94/07316 PCI'/US93/08674 .

J. ~ 41 .5 ~1 Im.h /* Im.h * COPYRIGHT 1992 ADAPTIYE CORPORATION
* ALL RIGHTS RESERVED
**/
AAAAAAAAAAAAAAAAA-AAAAAAAAAAAAAC~l~A~.AAAAAAAAAAAAAAAAAAA~AAAAAAAAAAAAAAAAAAAAA/
#Hndef LM H
#deflne LM- H
#define LM VB QUIET (0) #define LM VB ERRS (1) #define LM-VB TERSE (2) #define LM VB VERBOSE (3) #define LM VB MSGS (4) #define LM VB ALL (999) #define CHK VB(level) (tcb->verbose ~= level) #define LM MAX VLAN NAME (17) #define LM INDENT (2) #define LM-DFLT MTU SIZE (9100) #define LM DFLT NUM MCASTS (4) #define LM MAX MLID (256) #define LM MAX BID (1024) #define LM-MAX_MID (1024) #define MAX SLOTS (16) #define MAX PORTS PER SLOT (8) #define MAX PORTS rMAX SLOTS * MAX PORTS PER SLOT) #define LM ML EX (EX INDI~ATION) #define LM AAL EX MSK- (M EX INDICATION) #define LM START VCI (0x3000) #define LM END VCI (0x3ff #define LM-INSTANCE (0) #define LM ML SID (MAKE SSID~TID LM, LM INSTANCE, LM AAL E)O
#define U~A EX l~lSK (M EX INDlcATRoN) #define SIZ-E IAlD BITS ~ MAX MID / (8 * SIZE BITS)) #define SIZE MUD BITS (U~MAX MUD / (8 * SIZE BITS)) #define SIZE BID ~ITS (LM 1iAAX BID / (8 * SIZE BTTS)) #define LM ~LR l;;lAC ADDR~maddr)\
((maddr)->aa1Ong[0] = (maddr)-~aa long[11 = 0, (maddr)->aa type = MT MAC) #define LM CLR PORT ADDR(paddr)\
((paddr)->aa Tong[o~= (paddr)->aa long[1] = 0, (paddr)-~aa type = MT PORT,\
(paddr)->aa country= USA) #define U~ll CLI~ VC ADDR(vcaddr) \
((vcaddrF>vlan 1~= O, LM CLR_MAC ADDR(&((vcaddr)->mac addr))) #define LM INIT PORT ADDR~paddr, node, shelf, slot, port) \
(LM CU~ POR-T ADDR(paddr),\
(paddr)->aa node = node, (paddr)->aa shelf = shelf, (paddr)->aa_slot = slot,\

WO 94/07316 2 1 4 ~ I PCI/US93/08674 Im.h _9, (paddr)->aa port = port, (paddr)->aa lannum = 0) #define LM INIT iVlLAC ADDR(maddr, mac addr)\
('maddr'->aa iong[0] = (mac addr)-~aa iong[0], \
'maddr->aa long[11 = (mac addr)->aa long[1], \
maddrl->aa type = MT iViAC) #de;ine LiV INIT VC ADDR(vcaddr, vid, maddr)\
(LM CLR-VC ADDR(vcaddr), (vcaddr)->vian id = (vid),\
LM -iNlT MAC ADDR(&((vcaddr)->mac add~, maddr)) #define LM NUM Fl F~ ry) (~keoi'(aly) / skeof((ary)l0l)) #define BUliD IT~:H(Hdr, len, generic, Instance, exch, mtype, mytld) \
{Hdr.Length=len;
Hdr.De~t I ~hel Pid =0;
Hdr.Dest I RhPl Sj(~ = \
MAKE SSlD(generic,instance,exch);\
Hdr.Dest.Net- LOCAL Ni_T;
Hdr.Dest.Node = Loc~L NODE;
GetPid(&Hdr.Orig I RhPI PITd);
Hdr.Orig I ~hel S;-l = \
MAKE SSlD(mytid.Generic, 0, EX INDICATION);\
Hdr.MsgType = mtype;}

typedef tUlNT32 Im mlid t;
typedef tUlNT32 Im bid t;
typedef tUlNT16 Im vian id t;
typedef struct Im prefix s {
u"siy"ed pri:2;
u"~;y"ed tag a:6;
u"~iyl ,ed fill1.2;
unsigned rp:1;
u"sig"ed nrc:1;
unsigned cos:4;
u"~iyl,ed fill2:1;
u~,siy"ed br:1;
unsigned vem:1;
u~ ~siyl ,eci mb:1;
l",siy"eci tag b:4;
u"~;y,.ed fill3.2;
u":,;y"ed tag c:6;
} Im prefK t;
#define SIZE LM PREFIX (skeor(l", prefK t)) #define CLR PREFlX(pfx) (*((tUlNT32*)(pfx)) = 0) #define BUILD UCAST PREFlX(pfx, shelf, siot, port)\
(CLR PREFrX(pfx), ~pfx)->tag a = shelf, (pfx)-~tag b = slot, \
(pfx)->tag c = port, (pfx)->rp = 1) /* FK RPA 10 i iar 92 */

W O 94/07316 PC~r/US93/08674 .

Im.h #define BUILD MCAST PREFlX(pfx, bid)\
(CLR PREFI~(pfx), (pfx)->br = 1, (pfx)->tag a = (((bid) & 0xfc00) > > 10),\
(pfx)->tag b = (((bid) & 0x03c0) > > 6), (pfx)->tag c = ((bid) & Ox003fl) typedef struct Im atm hdr s {
unsigned gfc:4;
unsigned vpi:8;
u- slgl .ed vc1:16;
u..~ly.,ed pt:2;
u"si~..ed rsvd:1;
Ul.~ .ed clp:1;
} Im atm hdr t;
#define SIZE Li i ATM FiDR (:.keclt(l... atm hdr t)) #define CLR ATM HDR(hdr) (*((tUlNT32*)(hdr)) = 0) #define BUILD Al~M HDR(hdr, the vcl)\
(CLR ATM HDR(hdr), (hdr)->vcl = the vci) typedef struct Im alan cfg enq s {
struct Iml hdr Imi hdr;
tALANCF~ ENQ enq;
} Im alan cfg enq t;
#defineSlZE LM AiAN-CFG ENQ (skeur(i... alan cfg enq t)) _ typedef struct Im alan cfg resp s {
struct Imi hdr Imi hdr;
tALANCFG ENQ enq;
tALANCFG RESP resp;
} Im alan cfg resp t;
#define SIZE L-M Ai AN-CFG RESP (skaui(i--- alan cfg resp t)) typedef struct Im es cfg resp s {
struct Imi hdr Imi hdr-tCFGELEivi enq;
tCFGELEM resp;
tPORT CFGELEM paddr[1];
Im es cfg resp t;
#define SIZE i~l ES ~:FG RESP (sl~eorQI~ es cfg resp t)) _ typedef struct Im es cfg enq s {
struct Imi hdr ImT hdr;
struct config elern enq;
} Im es cfg ena t;
~define SIZE i-~i ES Z~FG ENQ (~,~eorQm es cfg enq_t)) typedef struct atm addr Im mac addr t;
#define SIZE LM MAC ADbR (~kt:orQI-- mac addr t)) typedef struct atm addr Im port addr t;
~define SIZE LM PORT A~DR ~ (s,~eor(l", port addr t)) WO 94/07316 ~ 1 ~ 4 1 ~ ~I Pcr/US93/08674 /~/
Im.h typedef struct Im_vc addr s {
Im vlan id t vlan id struct atm addr mac addr;
} Im vc addr t;
;~define SIZE LM ~C ADDR (~, eotQ", vc addr t)) #define aa country aa u~aaw-~cw nibble2 #define aa shelf aa u.aaw.aasw nibble3 #define aa slot aa~u.aaw.aasw nibble4 #define aa~port aa u.aaw.aasw nibble5 typedef struct Im tcb s {
tTlD mytld.
tPlD mypid;
struct TimerBlock *tmr blk;
tUlNT32 timerid;
tUlNT32 Li.l.er~ry tATMADDR nac atm addr;
tUlNT32 nac id tML KEY my aal key;
tUlNT32 my node;
tUlNT32 my shelf;
tUlNT32 my slot;
Im port addr t port tmplt;
tUrNT32 cur brd;
bits t bid bits[SlZE BID BITS];
bits t mlid bits[SlZi~ MLID BITS];
tUlNT32 dflt mtu size;
tUlNT32 dflt nurn mcasts;
tUlNT32 verbose;
tUlNT32 do cfg wrts;
char vc addrbuf[200];
char mac addr buf[s, eof(ll" mac addr t) * 3 char port addrbuf[4o~;
char vlan id buf[10~;
queue t port queue;
queue t vlan_queue;
queue t mac queue;
queue t mv queue;
queue t pv queue;
queue t vc queue;
queue~t *port q;
queue t *vlan q;
queue t *mac_q;
queue t *mv q;
queue t *pv q;
queue~t *vc q;
} Im tcb t;
#define SIZE LM TCB (skeot(l", tcb t)) W O 94/07316 PC~r/US93/08674 ~.
~ J ~ 4 1 5 ~ /31m.h typedef struct Im mac s {
qlink t mac Irnk;
queue t mv queue;
queue t *mv q;
struct rm port s *port;
Im mac addr t mac addr;
bits t mlid bits~SlZE ivii iD BITS];
} Im mac t;
#define SIZE 13~i ~iAC ( ikeor~l mac t)) typedef struct Im van s {
qlink t vian irnk;
queue t pv queue;
queue t *pv q;
queue t mv queue;
queue t *mv q;
queue t vc queue;
queue t *vc q;
queue t free vc queue;
queue t *free vc q;
Im vian id t vian id-tUrNT32 mtu size;
tUlNT32 num mcasts;
Im mlid t dflt mlid-char vian name[UM MAX ViAN NAME];
bits t mid bits[SlZE IVilD BITS];
} ~ Im vian t;
#define SIZE i M Vi AN (sizeof(lm vian t)) typedef struct Im port s {qlink t port irnk;
Im port addr t port addr;
Im~mac~t ~ *mac queue t pv queue;
queue t *pv q-bits t mlid bits[SlZE MUD BITS];
} Im port t;
#define SIZE ~i i ~SRT (skeor(i port t)) typedef struct Im vc s {
qlink t vc ilnk;
qlink t vian link;
Im vran t *vian;
Im vc addr t vc addr;
Im bid t bid;
tUrNT32 ref cnt;
} Im vc t;
#define SIZE i- M VC (sizeof(lm vc t)) W O 94/07316 2 1 4 ~ ~ 5 ~ PC~r/US93/08674 _ /~ . .
Im.h typedef struct Im port vian s {
qlink t pv iink;
qltnk t port link;
qlink t vian link;
Im vran t *vian;
Im port t *port;
Irn mlld t mlid;
Im vian W t vian id;
Irn port addr t port addr;
} ~ ~ Im port vian t;
#define SIZE W PORT-VLAN (sk~:ot(llll port vian t)) _ typedef struct Im mac vian s {
qlink t mv link;
qlink t mac link;
qlink t vian iink;
Im rnac t *mac;
Im~vian t *vian-Im vian id t vian id;
Im~mac addr t mac addr;
tUrNT1 6 mld;
Im mlid t mlid;
} ~ ~Im mac vian t;
#define SIZE L-M M-AC VIAN (skeor(ll" mac vian t)) typedef struct Im cfg glbl s {
tUlNT32 dflt mtu ske;
tUlNT32 dflt num mcasts;
} Im cfg glbl t;-#define SIZE LN CFG GLBL (sk~or(ll" cfg glbl t)) _ typedef struct Im cfg vian s tUlNT32 dflt mlid;
tUlNT32 num mcasts;
tUlNT32 mtu size;
char vian name[W MAX VLAN NAME];
} Im cfg vian t;
#define SIZE W t~FG VLAN (skeofQ", cfg vian t)) _ typedef struct Im cfg port s {tUlNT32 el tonto, } . Im cfg port t;
#define SIZE W C-FG FORT (siceor(i", cfg port t)) typedef struct Im cfg mac s {
tUlNT32 el tonto;
Im cfg mac t;
#define SIZE LN CFG MAC (ske.)f(llll cfg mac t)) typedef struct Im cfg pv s {

W O 94/07316 : PC~r/US93/08674 Im.h tUlNT32 miid;
} im cfg pv_tj (skeurQlll cfg pv t)) typedef struct Im cfg mv s {
tUlNT32 mli~;
} Im cfg mv t;
#deflne SIZE LlUi CFG ~iV (sk~urQ~ cfg mv t)) typedef struct Im cfg vc s {
tUlNT32 el tonto;
#define SIZE i~r Ct-G VC (si~eot(l-n cfg vc t)) _ typedef struct Im glbl cfg key s {
tUlNT32 tag;
} Im glbl cfg key_t;
#define SIZE i~ t~LBL-CFG KEY (si~otQ... glbl cfg key t)) typedef struct Im vian cfg key s {
tUlNT32 tag;
Im vian Id t vlan id;
} Im vian c~g key t;
#define SIZE iM Vi~AN-CFg KEY (si~ur(llll vian cfg key t)) typedef struct Im port cfg key s {
tUlNT32 tag;
Im port addr t port addr;
} Im port cfg key t;
#define SIZE i M P~RT-CFG- KEY (si~eo~(l--- port cfg key t)) _ typedef struct Im mac cfg key s {
tUlNT32 tag;
Im mac addr t mac addr;
} Im mac cfg key t;
#define SIZE LM M-AC -CFG-KEY (si~or(l--- mac cfg key t)) typedef struct Im vc cfg key s {
tUlNT32 tag;
Im vc addr t vc addr;
} Im vc cfg key t;
#define SIZE ~i VC -CFG-KEY (s~of~m vc cfg key t)) _ typedef struct Im pv cfg key s {
tUlNT32 tag, Im port addr t port addr;
Im vian Id t vian rd;
} Im pv cfg key t;
#define SIZE ~i PV ~FG-KEY (skeot(il,~ pv cfg key t)) W O 94/07316 2 ~ 5 4 PC~r/US93/08674 /3~-lm.h ~7-typedef struct Irn mv cfg key s {
tUlNT32 tag;
Im mac addr t mac addr;
Im vlan~d t vlan Id, } Im mv cfg key t;
#define SIZE CM MV CFG~<EY (s,~eofa", mv cfg key t)) typedef union cfg key u {
tUlNT32 tag;
Im glbl cf~ key t glbl key;
Im vlan cfg key tvlan key;
Im~port~cfg~key t port key;
Im mac cfg key t mac key;
Im vc cfg key t vc key, Im pv cfg key t pv key;
Im mv cfg key t mv key;
} Im cfg key t;
#define SIZE ~ CFG l~EY (si~eo~ " cfg key t)) #define NULL_CFG KEY (0' #define GLBL CFG KEY (1 #define VLAN CFG KEY (2;
#define PORT CFG KEY (3) #define MAC CFG REY (4) #define VC CFG KEY (5) #define PV CFG KEY (6) #define MV CFG KEY (7) #ifdef UNIX
extern tlNT8 *GlobalP;
#undef printf #endif #define malloc(size) GetMem(size) #define free(ptr) FreeMem(ptr) #define FREE Q(q, proc) ((~nt)traverse q(q, proc, NULL)) #define FREE MV Q(q) FREE Q(q, free mv) #define FREE PV Q(q) FREE Q(q, free pv) #define FREE MAC Q(q) FREE Q(q, free mac) #define FREE VLAr~ Q(q) FREE Q(q, free vlan) #define FREE PORT Q(q) FREE Q(q, free port) #define FREE-VC QTq) FREE Q(q, free vc) #define FREE-PO-RT VLAN Q(q) ~REE Q(q, free port vlan) #define FREE MAC VLAN Q(q) FREE_Q(q, free mac vian) #define FREE MAC MV_Q~q) FREE Q(q, free mac mv) #define FREE VLA~ MV Q(q) FREE Q(q, free vlan mv) #define FREE PORT PV Q(q) FREE Q(q, free port pv) #define FREE~VLAN~PV~Q(q) FREE~Q(q, free vlan pv) W O 94/07316 PC~r/US93/08674 2~4~15~ ~3~
Im.h #define ATCH MAC MV Q(q, mac) ((int)traverse q(q, atch mac mv, mac)) #define ATCH VLAN MV Q(q, vian) ((int)traverse q(q, atch_vian mv, vian)) #define ATCH PORT PV Q(q, port) ((int)traverse q(q, atch port pv, port)) #define ATCH Vi~N PV Q(q, vian) ((int)traverse q(q, atch vian pv, vian)) #define ATCH MV MAC Q(q, mv) (int)traverse q(q, atch mv mac, mv)) #define ATCH MV VLAN Q(q, mv) (int)traverse q(q, atch mv vlan, mv)) #define ATCH PV PORT Q(q, pv) (,Int)traverse q(q, atch pv port, pv)) #define ATCH PV VLAN Q(q, pv) ((int)traverse q(q, atch pv vian, pv)) #define FIND MAC(q, mac) ((Im mac t*)traverse q(q, cmp mac, mac)) #define FlND~PORT(q, port) ((Im port t*)traverse q(q, cmp port, port)) #define FIND VLAN(q, vlan) ((Im vian t*)traverse q(q, cmp vian, vian)) #define FIND VC(q, vc) ((Im vc t*~traverse qrq, cmp vc, vc)) #define FIND MV(q, mv) ((Irn mac vlan t*)traverse q¦q, cmp mv, mv)) #define FIND PV(q, pv) ((Im port vian t*)traverse q(q, cmp pv, pv)) #define FIND MLiD(q, mlid) ((im mac vian t*)traverse q(q, cmp mlid, mlid)) #define FlNDNi--XT MAC(q, mac) ((im mac t*)traverse q(q, cmpnext mac, mac)) #define FINDNEXT PORT(q, port) ((Im port t*)traverse q(q, cmpnext port, port)) #define FINDNEXT Vi AN(q, vian) ((Im vian t*)traverse q(q, cmpnext vian, vian)) #define FINDNEXT VC(q, vc) ((Im vc t*)traverse q(q, cmpnext vc, vc~) #define FINDNEXT MV(q, mv) ((Im mac vian t*)traverse q(q, cmpnext mv, mv)) #define FlNDNEXT~PV(q, pv) ((Im port vlan t*)traverse q(q, cmpnext pv, pv)) #define FINDNEXT MUD(q, mlid) ~(lm mac vian t*)traverse q(q, cmpnext mlid, mlid)) #define PUTQ_SORTED MAC(link, q) (putq sorted(link, q, qpsc mac)) #define PUTQ SORTED PORT(link, q) (putq sorted(link, q, qpsc port)) #define PUTQ SORTED~VLAN(link, q) (putq sorted(link, q, qpsc vian)) #define PUTQ SORTED VC(link, q) (putq sorted(link, q, qpsc vc)) #define PUTQ SORTED~PV(link, q) (putq sortedQink, q, qpsc pv)) #define PUTQ~SORTED~MV(link, q) (putq sorted(link, q, qpsc mv)) #define PRINT Q(q, proc, Indent) ((int)traverse q(q, proc, indent)) #define PRINT VLAN Q(q, indent) PRINT Q(q, print vian, indent) #define PRINT-MAC ~(q, indent) PRlNT~Q(q, print mac, indent) #define PRINT-PORT- Q(q, indent) PRli~Q(q, prlnt port, indent) #define PRINT PV Q~q, indent) PRINT Q(q, print pv, indent) #define PRINT MV Q(q indent) PRINT Q(q, print mv, indent) #define PRlNT~VC~Q(q Indent) PRlNT~Q(q, print vc, indent) #define pG cbA'r'at~ ((im tcb t*)GlobaiP) #define DEFINE TCB Im tcb t *tcb #define SETUP TCB Di~FlNE TCB z pr c~ )51t:~
extern struct AgentMsg *Im cp mgmt msgO;
extern Im es cfg resp t *Im build es cfg respO;
extern Im mac t *add mac~
extern Im port t *add portO;

91 ~ PCr/US93/08674 WO 94/07316 ~ 1 J ~

/~7 ; . . I.
Im.h extern Im vlan t *add vlanO;
extem Im vc t *add vcO;
extem Im~vc~t *~et free vcO;
extem Im vc t *add free vcO;
extern Im mac vlan t *add mvO;
extem Im port vlan t *add ~vO;
extern Im~mac t *cmp mac~;
extem Im~port~t *cmp~port(;
extern Im vlan t *cmp vlanC;
extern Im~vc t *cmp vcO;
extern Im~port vlan t *cmp pvO;
extem Im~mac vlan t *cmp mvO;
extem Im mac vlan t *cmp mlidO;
extem Im~mac~t *cn pnext macO;
extern Im~port~t *cmpnext~portO;
extem Im~vlan t *cmpnext vlanO;
extern Im~vc t *~ pn~ ~t vcO;
extem Im port vlan t *cmpnext pvO;
extern Im~mac vlan t *cmpnext mvO;
extem Im mac vlan~t *cmpnext mlidO;
extem int qpsc macO;
extem int qpsc portO;
extern int qpsc~vianO;
extem int qpsc vcO;
extem int qpsc pvO;
extem int qpsc~mvO;
extern int atch mac mvO;
extem int atch vian mv~;
extem int atch port pvr;
extem int atch vian pv;
extem int atch~pv vian;
extern int atch pv portu;
extern int atch mv macO-extem int atch mv vianO
extern int free macO;
extern int free~vianO;
extern int free portO;
extern int free~vcO;
extem int free~port vianO;
extem int free~mac~vianO;
extern int free mac mvO;
extem int free~vian~mvO;
extem int free~port~pvO;
extern int free vian pvO;
extern int free~mvO
extem int free~pvO;
extern int print macO;
extern int print~vianO;
- extern int print~portO;
extern int print vcO;

., .
-W O 94/07316 ; PC~r/US93/08674 214~1 5ll Im.h extern int print mvO;
extern int print~pvO;
extern char *sprTnt mac addrO;
extern char *sprint port addrO;
extem char *sprint vian idO;
extern char *sprint~vc addrO;
extern struct Ti",er'31oc4 *TimerinitO;
#endif /* ifndef LA~ H */

WO 94/07316 2 1 ~ 4 ~ 5 ~ Pcr/US93/08674 /39 . .. :
Im cfg.c /* Im cfg.c * COPYRlGi-iT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
*/

#Hdef CERNEL
#include ipc def.h #include~net def.h~
#include <global def.h>
s~lnclude cdriver.h>

#undef Im init #else /* Hndef CERNEL */
#include cstdint.h>
#include <globai def.h>
#include ~ITC if.h>
#include <driver.h>
#include <RT H.h>
#include <timer.h>
#include <RT def.h>
#include <enet if.h>
#include <net aef.h>
#define ERRLOG printdbg #define printf plillLcllJg #endH /* ifdef CERNEL */
#include ~unipdu.ha #include ~nnipdus.h #include~altask gl.h~
#include sigtas~ gl.h~
#include Usvctask_gl.h~
#include~svc H.h~
#indude~snmp incl.h~
#include~ML Hh~
#indude~wdb H.h~
#Include ~q.h #include ~bits.hU
#include ~Im.h~
#define WDB VERS (1) #define WDB PRI (1) Pcr/US93/08674 .

214~ Im cfg.c lm chg glbl cfg(dflt mtu size, dflt num mcasts, nac addr, bid bits, mlid bits) tUlNT32 *dflt mtu ske;
tUlNT32 *dflt num mcasts;
tATMADDR *nac addr;
bits t *bid bits, bits t *mlid bits;
Si_TUP TCB;
if (dflt mtu size != NUil) {
tcb->dflt mtu size = *dflt mtu_size;
if (dflt num mcasts l= NUil) {
tcb ~dflt num mcasts = *dflt num mcasts;
if (nac addr != NUil) {
tcb->nac atm addr= *nac addr;
}

if (bid bits != NUil) {
bcopy(bid bits, tcb->bid bits, sizeof(tcb->bid bits));
i}f (mlid bits !- NUil) {
bcopy(mlid bits, tcb->mlid bits, ~ eo~(k;b->mlid bits));
}

Im wrt glbl cfgO;
}

Im chg vian cfg(vian, dflt mlid, num mcasts, mtu size, vlan name) lm vlan t *vian;
tUrNT32 *dflt mlid;
tUlNT32 *num mcasts;
tUlNT32 *mtu_size;
tUlNT32 *vian name;
{

qiink t *link;
Im mac t *mac;
Im~mac~vian t *mv;
Si TUP_TCB, if (dflt mlid != NUil) {
if (~dflt mlid >= L~i MAX Mi iD 1 1 Ibits tst bit(*dflt mlid, tcb->mlid bits, SIZE MUD BITS)) {
if (vian->dflt mlid < LM MAX M~ID) ~
bits free bit(vian->dflt mlid, tcb->mlid bits, SIZE MLiD BITS);
if (*dflt mlid < iM MAX Mi iD) {
bits alloc bit(*dflt mi~d, tcb->mlid bits, STZE Mi iD BITS);
}

wo 94/07316 2 1 ~ 4 1 ~ ~ Pcr/US93/08674 Im cfg.c 1 ;., . ~ b ,,' vlan->dflt mlid = *dflt mlid;
} }
K (num mcasts l= NULL) {
chg num vcs(vian, *num mcasts);
H (vian name l= NULL) {
- Int name len;
name len = strien(vian name);
name~len = (name len ~ LM MAX VLAN NAME) ? name len:
Lh~ MAX VLAN NAME - 1, bcopy~vian name, vian-~vian name, name ien);
vian->vlan name[name len] = O;
K (mtu size l= NUil) {
vian->mtu size = *mtu size;
}

Im wrt vian cfg(vian);
for (llnk = ~EAD Q(vian->mv q); link l= NULL;
link = link->next) {
mv = (Im mac vlan t *) link->data;
mac= mv->mac;
H (mac l= NULL) {
} Im_send_es_cfg_ind(mac);

Im chg port cfg(port, mac addr, mlid bits) ~m port t *port;
Im mac~addr t *mac addr;
bit- t - ~mlid bits, Im mac t *mac-SETUP TCB;
K (mac addr l= NULL) {
K (port->mac l= NULL) {
mac = port->mac;
free_mac(mac);
mac = add ,"ac(,.,ac addr);
atch mac port(mac, port);
Im dup port dflts(port, mac);
K (mlid bits l= NULL) {
bcopy(mlid bits, port->mlid bits, skeu~o,l->mlid bits));
Im wrt port cfg(port);

PC~r/US93/08674 /~
21441~ ~ Imlcfg.c }

Im chg mac cfg(mac, mlid bits) lm mac t- *mac;
{ bits_t *mlld bits;
SETUP TCB;
if (mlid bits l= NUil) {
bcopy(ml~d bits, mac->ml~d bits, skeof(mlid bits));
} Im_wrt_mac_cfçj(mac);
Im chg vc cfg(vc, bid, ref cnt) ~m vc t *vc;
Im bi~t *bid;
tUrNT32 *ref cnt;
SETUP TCB;
- if (bid l= NUil) {
if (!bits tst bit(*bid, tcb->bid bits, SIZE BID BITS)) {
bits free bit(vc->b~d, tcb->b~d bits, ~IZE BID BITS);
bits alloc bit(*bid, tcb->bid bits, SIZE BrD BiTS);
vc->bid - *bid;
} }
if (ref cnt l= NULL) {
vc->ref cnt = *ref cnt;
Im wrt vc cfg(vc);
}

Im chg pv cfg(pv, mlid) ~m port vian t *pv;
tUrNT32 *mlid;
Im port t *port;
Si-TUP TCB;

port = pv->port;
H (mlid l= NUil && pori. I= NUil) {
if (~bits tst bit(*ml~d, port->mlid bits, SIZE MUD BITS)) {
bits free bit(pv->mlid, port->mlid bits, SIZE Mi ID BITS);
bits alloc bit(*mlid, port->mlid bits, SIZE i ii~D Bi~S);
pv->mlid - *mlid;
}
}

W O 94/07316 ~ 5 ~ PC~r/US93/08674 Im cfg.c ~, . .
~05 } Im-wrt-pv-cf9(pv);
Im chg mv cfg(mv, mlid) 7m mac van t *mv;
tUllilT32 *mlid;
- Im mac t *mac;
SE~UP TCB;
mac = mv-~mac;
if (mlid l= NULL && mac l= NUU ~ {
if ~Ibits tst bit(*mlid, mac-~mlid bits, SIZE MUD BITS~ {
bits~free bit(mv->mlid, mac->mlid bits, SIZE ~iUD BITS~;
bits~alloc bit(*mlid, mac->mlid bit-s, SIZE Mi~lD BI~S);
mv->mli~= *mlid;
} }
Im wrt mv_cfg(mv);
if ~mac l= NULL) {
} Im_send_es_cfg ~nd(mac);

Im rm glbl cfgO
Im glbl cfg key t key;
Im cfg glbl t cfg SE~UP TC~;
key.tag = GLBL CFG KEY;
wdb send remove noack~&key, skeof(key));

Im rm vian cfg(vlan) Im vian t *vlan;
Im vian cfg key t key;
Im cfg vlan t cfg;
SE~UP TCB, - key.tag = VLAN CFG KEY;
key.vlan id = vian->vlan id;
wdb send remove noack(8key, sizeof(key));

Im rm port cfg~port) Im port t *port;

Pc~r/US93/08674 21441 5~ Im _cfg.c {

Im port cfg key t key;
Im~cfg por~~t cfg;
SErUP TCB, key.tag = PORT CFG KEY;
key.port addr= port-~port addr;
wdb send remove noack(&key, skeof(key));

Im rm mac ~y(~ac) { lm_mac t *mac;
Im mac cfg key t key;
Im cfg mac~t cfg;
SI~UP TCB, key.tag = MAC CFG KE~';
key.mac addr- mac->mac addr;
wdb send remove noack(&key, sizeof(key));
}
Im rm_vc c~g(vc) Im vc t *vc;
Im vc cfg key t key;
Im~cfg vc-t -cfg;
SETUP TCB;
key.tag = VC CFG KEY;
key.vc addr- vc->vc addr;
wdb send remove noack(&key, sizeof(key));
}
Im rm pv cfg(pv) lm_port vlan t *pv;
Im pv cfg key t key;
Im cfg pv-t ~cfg;
S~UP TCB;
key.tag = PV CFG KEY
key.port addr= pv->port_addr;
key.vlan id = pv-~vlan id, wdb send remove noack(&key, sizeof(key));

}

PC~r/US93/08674 W O 94/07316 ~ 1 4 ~Y~
Im cfg.c ~07-lm rm mv cfg(mv) lm mac van t *mv;
Im mv cfg key t key;
Im cfg mv t cfg;
SETUP T~B;
.. _ key.tag = MV CFG KEY;
key.mac addr = mv->mac addr;
key.vian~id = mv->vian id, wdb send remove noack(&key, sizeof(key)~;

Im wrt glbl cfgO
Im glbl cfg key t key;
Im cfg glbl t cfg;
SETUP TCB;
if (tcb-~do cfg wrts) {
key.tag - GLBL CFG KEY;
cfg.dflt mtu size = tcb->dflt mtu size;
cfg.dflt num mcasts = tcb->-dflt num mcasts;
wdb send store noack(&key, sizeof(key), &cfg, sizeof(cfg~, WDB VERS, WDB PRI);

Im wrt vian cfg(vian) im vian t *vian;
Im vlan cfg key t key;
Im~cfg vlan~t cfg;
SETUP TCB, if (tcb->do cfg wrts) {
key.tag - VI~N CFG KEY;
key.vian id = vian->vran id;
cfg.dflt mlid = vian-~dflt mlid;
cfg.num mcasts = vian->num mcasts;
cfg.mtu size = vian->mtu ske, bcopy(v~an-~vian name, cfg.vian name, sizeof(cfg.vlan name));
wdb send store noack(&key, sizeof(key), &cfg, sizeof(cfg), WDB VERS, WDB PRI);

Pcr/US93/08674 214~15~ Im cfg.c Im wrt port cfg(port) Im port t *port;
Im port cfg key t key;
Im cfg port t cfg;
SETUP TCB, If (tcb->do cfg wrts) {
key.tag - P~RT CFG KEY;
key.port addr = port->port addr;
cfg.el tonto = O;
wdb send store noack(&key, sizeof(key), &cfg, sizeof(cfg), WDB VERS, WDB PRI);
}

}
Im wrt mac cfg(mac) ~m=mac t *mac;
Im mac cfg key t key;
Im cfg mac t cfg;
SElUP TCB, H (tcb->do cfg wrts) {
key.tag - MAC CFG KEY;
key.mac addr- mac->mac addr;
cfg.el tonto = O;
wdb send store noack(&key, sizeof(key), &cfg, sizeof(cfg), WDB_ VERS, WDB PRI);

} }
Im wrt vc cfg(vc) 7m vc t *vc;
{

Im vc cfg key t key;
Im~cfg vc-t -cfg;
SETUP T~B;
H (tcb->do cfg wrts) {
key.tag - VC CFG KEY;
key.vc addr - vc->vc addr;
cfg.el tonto = O;
wdb send store_noack(&key, sizeof(key), &cfg, sizeof(cfg), WDB VERS, WDB PRI);

WO 94/07316 2 1 ~ PCr/USg3/08674 "~,~ , .
Im cfg.c `
--i os }

Im wrt_pv cfg(pv) 7m port vian t *pv;
Im pv cfg key t key;
Im cfg pv t ~cfg;
SETUP T~B;
_ if (tcb->do cfg wrts) {
key.tag = PV CFG KEY;
key.port addr= pv->port addr;
key.vian id = pv->vlan id, cfg.mlid = pv->mlid;
wdb send store noack(&key, skeof(key), &cfg, skeof(cfg), WDB ~ERS, WDB PRI);
}

Im wrt mv cfg(mv) Im mac vian t *mv;
Im mv cfg key t key;
Im cfg mv t cfg;
SE~UP TCB;
if (tcb->do cfg wrts) {
key.tag - MV CFG KEY;
key.mac addr= mv->mac addr;
key.vian id = mv->vian id, cfg.mlid = mv->mlid;
wdb send store noack(&key, sizeof(key), &cfg, skeof(cfg), ~DB VERS, WDB PRI);

Im crt cfg(key, kien, cfg, clen) lm cfg key t *key;
int lden;
tUlNT8 *cfg;
int cien;
switch (key->tag) {
case NULL CFG KEY:
break;
case GLBL CFG KEY:
Im crt glbl cfg(key, cfg);
break, Pc~r/US93/08674 214~154 Im _cfg.c -1 1~
case VLAN CFG Ki~Y:
Im crt ~an c~g(key, cfg);
break-case PORT CFG i~EY:
Im crt port cfg(key, cfg);
break-case MAC CFG K}Y:
Im crt mac cfg(key, cfg);
break, case VC CFG KEY:
Im crt vc cfg(key, cfg);
break case PV CFG KEY:
Im crt pv cfg(key, cfg);
break case MV CFG KEY:
Im crt mv cfg(key, cfg);
break;
default:
break;
}
Im crt glbl cfg(key, cfg) ~m glbl cfg key t *key-Im_cfg glbl t *cfg;
SETUP TCB;
Im chg glbl cfg(&cfg->dflt mtu ske, &cfg->dflt num mcasts, NULL, NULL, NULL), }
Im crt vlan cfg(key, cfg) Im vlan cfg key t *key;
Im_cfg_~an t *cfg;
Im vlan t *vlan;
qlink t *link;
Im rnac vlan t *mv;
Im~mac~t ~ *mac-Si_TUP ~CB;
vlan = FIND VLAN(tcb->vlan q, key->vlan Id);
if (vlan == NULL) ~
vlan = add vlan(key->vlan id, cfg->mtu ske, cfg->num mcasts, cfg->vlan_name);
Im chg vlan cfg(vian, &cfg->dflt mlid, &cfg->num mcasts, &cfg-> mtu size, &cfg->vian name);

W O 94/07316 2 1 ~ 4 1 ~ ~ PC~r/US93/08674 ,~q Im cfg.c }

Im crt port cfg(key, cfg) ~m port cf~ key t *key;
Im_cf3 port~t ~c-f~;
Im port t *port;
- S~UP TCB;
port = FIND PORT(tcb->port q, &key->port addr);
H (port == I~UIl) {
port = add port(&key->port addr);
}

Im crt mac cfg(key, cfg) Im mac cfg key t *key;
Im cfg mac t *cfg;
Im mac t *mac;
SETUP TCB;
mac = FIND MAC(tcb->mac q, &key->mac addr);
(mac == I~ULL) {
mac = add mac(&key->mac addr);
}

Im crt vc cfg(key, cfg) Im vc cfg key t *key;
Im~cfg vc-t -*cfg;
SETUP TCB;

Im crt pv cfg(key, cfg) lm pv cfg key t *key;
Im cfg pv-t -*cfg;
Irn port vlan t tmp;
Im port t *port;
Im~vlan~t *vlan;
Irn_port~vian t *pv;
SETUP TCB;
tmp.vlan id = key->vlan id;
tmp.port~addr= key->port addr;
pv = FIND PV(tcb->pv q, &tmp);
if (pv = = NULL) {

.
.

W O 94/07316 PC~r/US93/08674 ~ 1 4 ~
Im cfg.c ~12-port = FIND PORT(tcb-~port q, &key->port addr);
if (port == NUil) {
port = add port(&key->port addr);
if (vian == NULL) {
vian = add vian(key->vian id, tcb->dflt mtu size, tcb->dflt num mcasts);
pv = add pv(&key->port addr, key->vian Id, cfg->mlid);
Im chg pv cfg(pv, 8cfg->mlld);

Im crt mv cfg(key, cfg) 7m mv cfg key t *key;
{ Im_cfg_mv~t *cfg;
Im mac vian t *mv;
Im~mac~vian~t tmp;
Im mac t *mac;
Im~vian t *vian;
Si--TUP TCB;
tmp.vian id = key->vian id;
tmp.mac addr= key->mac addr;
mv = FIN7D MV(tcb->mv q, &tmp);
if (mv == NUil) {
mac = FIND MAC(tcb->mac q, &key->mac addr);
K (mac == NUiL) {
mac = add mac(&key->mac addr);
}

if (vian == NULL) ~
vian = add vian(key->vian id, tcb->dflt mtu size, tcb->dflt num mcasts);
mv = add mv(&key->mac addr, key->vian id, cfg->mlid);
Im chg mv cfg(mv, 8cfg->mlid);

PCI`/US93/08674 WO 94/07316 ~ 1 4 ~

,~, , Im mgmt.c /* Im mgmt.c * COPYRIGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED

AAAAAAA~AAAAAAAAAAAAAAAAAAAAAAAtNUAAAAA--AAAAAAAAAA~.AAAAAAAAAAAAAAAAAAA--AAAAAA/
#Hdef CLI .i~-#include~ipc def.h~
#include~net def.h~
#include <global def.h>
#include <driver.h>

#undef Im init #else /* ffndef CERNEL */
#include <stdint.h>
#include < global def.h >
#include <ITC if.h~
#include <driver.h>
#include <RT H.h>
#include <timer.h>
#include <RT def.h>
#include <enet F.h>
#include < net def.h >
#define ERRLOG pri l~di g #define printf printdbg ~endif /* ifdef CERNEL */
#include Uunipdu.h #include ~nnipdus.hU
#include~altask gl.hU
#include~sigtask gl.h~
#include~svctask gl.h~
#indude~svc H.h~
#include~snmp ind.h~
#include~ h~
#include ~q.h~
#include ~bits.h~
#include ~Im.h~
extern Im port vlan t *Im mgmt find pvO;
extem Im mac vlan t *Im mgmt find mvO;
extern Im vian t *Im mgmt find vianO;
extem Im port t *Im mgmt find portO;
-Pcr/US93/08674 21~41~ll Im mgmt.c extern Im mac t *Im mgmt find macO;extern Im vc t *Im mgmt fl'nd vcO;
extern Im port vian t *Im mgmt findnext pvO;
extem Irn mac vian t *Irn mgmffindnexf mvO;
extern Im vian t *Irn mgrnt findnext vian~;
extern Im port~t *Irn~mgmt~findnext~port(;
extern Irn mac t *Im mgmffindnext mac~;
extern Irn~vc t *lm mgmt findnext vcO;
Im srvc mgmt get(msg) struct A~entMsg *msg;
{

int ret;
ret = Im do mgmt get(msg, FALSq;
return (ret);~
}

Im srvc mgmt getnext(msg) struct AgentMsg *msg;
{ int ret;
ret = Im do mgmt get(msg, TRUE);
return (ret);
}

Im do mgmt get(msg, getnext) struct AgentMsg *msg;
int getnext;
{

int ret;
struct MB *mb;
struct MBH *mb hdr;
struct AgentMsg *tx msg;
ret = RT SUCCESS;
tx msg - lm cp mgmt nlsg(lllsg);
mb = &tx msg->Body, mb hdr- &mb->head;
mb hdr-~datoff = O;
switch (mb hdr->ovcode) {
case i~ G~BL OVN:
ret = Im mgmt get glbl(tx msg, getnext);
break;
case LM ATTR ENT OVN:
ret = Im mgmt get attr ent(tx msg, getnext);
break;

W O 94/07316 21~ PC~r/US93/08674 Im mgmt.c -11~
case LM PV OVN:
ret =~m mgmt get pv(t~ msg, getnext);
break;
case LM NODE ENT OVN:
ret =~m mgmt get node ent(tx msg, getnext);
break;
case LM MAC ENT OVN:
ret =~m mgmt get mac ent(tx msg, getnext);
break;
case LM MP ENT OVN:
ret = lm mgmt get mp ent(tx msg, getnext);
break;
case LM PM ENT OVN:
ret =~m mgmt~get pm ent(tx rnsg, getnext);
break;
case LM VC ENT OVN:
ret =~m mgmt get vc ent(tx msg, getnext);
break;
default:
ret= IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err exit;
break;
ret = Im send mgmt rsp(tx msg);
return (ret);
err exit:
Tm send mgmt rsp(tx msg);
} return (ret);

Im mgmt_get glbl(msg, getnext) struct AgentMsg *msg;
int getnext;
{

int ret;
struct MB *mb;
struct MBH *mb hdr;
struct OS tmp os;
int num vTans;
int num~ports;
int num rnacs;
int num~mvs;
int num pvs;
int num~vcs;
St-~TUP TCB;
N (CHK VB(LM VB MSGS)) {
prin~t('~uil,g globals\r\n~);

WO 94/07316 PCI'/US93/08674 2 1 ~ 5~
Im mgmt.c -11~

num vians = QUEUE LEN(tcb-~vian q);
num ports = QUEUE LEN(tcb-~port q);
num macs = QUEUE LEN(tcb-~mac ~;
num mvs = QUEUE rEN(tcb->mv q~
num pvs 3 oUEUEIEN(tCb-~PV Ci);
num vcs = QUEUE LEN(tcb-~vc q);
ret- RT SUCCESS, mb = &msg-~Body;
mb hdr = &mb-~head;
tmp os.length=~,~eur(lci~nac atm addr);
bcopy(&tci~nac atm addr, tmp os.bui~er, tmp os.length);
MB wp OS(mb, LM NAC ADDR PIX, &tmp os);
tmp os.length = skeof(tc~ bidbits);
bcopy(tcb-~bid bits, tmp os.bu~Fer, tmp os.length);
MB wp OS(mb, Llri BID PIX, &tmp os);
tmp os~ength = ske~,r(~ mlid brts);
bcopy(tcb-~mlid bits, tmp os.bu~er, tmp os.length);
MB wp OS(mb, LM MLID BITS PIX, &tmp os);
MB wp INT'mb, L~DFLT-MTlrPlX, &tcb-~dflt mtu ske);
MB wp INT'mb, LM DFLT-MCA-ST PIX, &tcb-~dflt num mcasts);
MB wp INT mb, LM-NUM-VLANS PIX, &num vians);
MB wp INT mb, LM NUM MACS ~IX, &num macs);
MB wp INT mb, LM NUM-PORT~ PIX, &num ports);
MB wp-liNT mb, LM-NUM-MVS PrX, &num mvs);
MB wp INT mb, LM NUM PVS PIX, &num pvs);
MB wp INT~mb, LM-i iUM VCS~PIX, &nurn vcs);
return (ret);
err exit:
return (ret);

Im mgmt get attr ent(msg, getnext) struct AgentMsg *msg;
Int getnext;
int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LiM ATTR ENT IDX *idx;
Im vlan t- *~an; ~
struct OS tmp os;
struct LM ATTR Ei iT IDX tmp Idx;
int ~ num macs;
Int num~ports;
SETUP TCB;
ret = RT SUCCESS;

WO~4/0731~ 21~ 1 PCI/US9J/08674 . .
/~
Im_mgmt.c mb = &msg->Body;
mb hdr = &mb->head;
idx - (struct LM ATTR ENT IDX *) mb hdr->iid;
vian = Im mgmffind vian(ldx);
if (vian =- NULI~ {
if (getnext) {
vian = Im mgmt flndnext vian(idx);
If (van == NULLl {
ret= IRT SUCCESS;
mb hdr->ercode = ER NOSUCHNAME;
goto err exit;
} else {
ret= IRT SUCCESS;
mb hdr->ercode = ER NOSUCHNAME;
goto err exit;

if (CHK VB(LM VB MSGS)) {
pri"L~("g~tli"g stats on van %d\r\n~, van->vian id);
num macs = QUEUE LEN(vian-~mv q);
num ports = QUEUE~EN(vian->pv q);
Im cvt vlan idx(&vian->vian id, &tmp idx);
*i~x = tmp idx;
Im cvt idx os(tmp idx LM_VLAN, LM NUM ELEM(tmp idx LM VLAN), &tmp os);
MB wp OS(mb, LM VLAN PIX, &tmp os);
tmp os.length = strien(vian->vian name);
bcopy(vlan->vian name, tmp os.buffer, tmp os.length);
MB wp OS(mb, L~r VLAN N-AME PIX, 8tmp os);
MB wp INT'mb, LM NUM MCAST PIX, &vian->num mcasts);
MB wp INT mb LM MTU SIZE Pl~, &vlan->mtu ske);
MB wp-iNT mb LM-MLiD- PlX,~vian->dflt mlid), MB wp INT mb LM ATTi~ NUM PORTS PIX, 8num ports);
MB wp iNT mb LM ATTR NUM MACS ~slX, &num macs);
tmp os.length = skeof(vian->mici bits);
bcopy(vian->mid bits, tmp os hu~er~ tmp os.length);
MB wp OS(mb, rM MID BITS PIX, &tmp os);
retum (ret);
err exit:
retum (ret);
Im mgmt get pv(msg, getnext) WO 94/07316 PCl/US93/08674 21~ 4 /5G
Im mgmt.c struct AgentMsg *msg;
Int getnext;
int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LN PV IDX *~dx;
struct Ll\f PV IDX tmp Idx;
Im port vTan t *pv;
struct OS tmp os;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr= &mb->head;
idx-- (stnuct LMi PV IDX *) mb hdr->iid;
pv = Im mgmt ~nd pv(idx);
if (pv == NUL~ {
if (getnext) {
pv = Im mgmt findnext pv(idx);
if (pv == NULC~ {
ret= !RT SUCCESS;
mb hdr->ercode= ER NOSUCHNAME;
goto err exit;
} else {
ret= !RT SUCCESS;
mb hdr->ercode = ER GENERIC;
goeo err_exit;

if (CHK VB(LM VB MSGS)) {
printf("getting stats on pv = \r\n");
} Print-pv(pv~ O);
Im cvt pv idx(pv, &tmp idx);
*idx = tmp idx;
MB wp INT'mb, LM PV SHELF PIX, &tmp ~dx LM PV SHELF);
MB wp INT mb, LM PV CARD PIX, &tmp Tdx LM PV ~ARD);
MB wp INT mb, LM-PV-PORT PIX, &tmp~idx LM PV PORT);
MB wp INT,mb, LM-PV MLID~IX, &pv->mlid);
Im cvt Tdx os(tmp ~ax LM PV VLAN, LM NUM ELEM(tmp idxLM PV VlANi), ~ ~&tmp os);~ ~ ~
MB wp OS(mb, LM PV VLAN Pl)C, &tmp os);
return ~et);
err exit:
return (ret);

2 1 ~ ~ ~ 5 ~ PCI~/US93/08674 /5~
Im mgmt.c lm mgmt get node ent(msg, getnext) struct AgentMsg msg;
int getnext;
Int ret;
struct MB *mb;
struct MBH *mb hdr;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr = &mb->head;

print tcb(tcb, O);
ret- IRT SUCCESS-mb hdr->ercode = ER GENERIC;
goto err exit;
return (ret);
err exit:
retum (ret);

Im mgmt get mac ent(msg, getnext) struct AgentMsg *msg;
int getnext;
{

int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LM MAC EN~ IDX *idx;
struct LM MAC ENT iDX tmp idx;
Im mac vian t~tmp~mv;
Im mac addr t mac addr;
Im~mac~vian t *mv;~
struct 0~ tmp os;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Bociy;
mb hdr= &mb->head;
idx - (struct i M MAC ENT IDX *) mb hdr-~iid;
mv = Im mgmt~ind rnv(idx~;
if (mv =- NULi~ {
if (getnext) {
mv = Im mgmt findnext mv(idx);
if (mv =- NUL~ {
ret= IRT SUCCESS;

WO 94/07316 PCr/US93/08674 21~15 1 '~
Im mgmt.c mb hdr-~ercode = ER NOSUCHNAME;
goto err exit;
} else {
ret= IRT SUCCESS;
mb hdr-~ercode = ER GENERIC;
~oto err exit;

if (CHK VB(LM VB MSGS)) {
prl,l~F~y~ul,g stats on mv = ~);
print mv(mv, 0);
Irn cvt mv idx(mv, &tmp idx);
*idx = tmp idx;
Im cvt idx os(tmp idxLM MAC VLAN, LM NUM ELi-M(tmp WxLM MAC VLAN), ~ ~&tmp os),~
MB wp OS(mb, LNi MAC VLAN PIX, &tmp os);
Im cvt idx os(tmp idx LM MAC ADDR, LM NUit1 ELEM(tmp idx LM MAC ADDR), &tmp os) MB wp OS(mb, iM MAC ADDR PIX, &tmp os);
MB wp~NT(mb, i M MAC MLiD PIX, &mv->mlid);
return (ret);
err exit:
return (ret);
}

Im mgmt get mp ent(msg, getnext) struct AgentMsg *msg;
int getnext;
int ret;
struct MB *mb-struct MBH *mb hdr;
struct LM MP ENT IDX *idx;
struct LM MP ENT_IDX tmp idx;
Im mac addr t mac addr;
Im mac t *mac;
Im port t *port;
Im port~addr t port addr;
struct OS ~tmp os;
int shelf;
Int slot;
int port num;
int nurn ~/ians;
SETUP TCB;
ret= RT SUCCESS;

W O 94/07316 2 ~ Pc~r/US93/08674 ~59 Im _ m g mt.c mb = &msg->Body;
mb hdr= 8mb-~head;
idx - (struct LM MP ENT iDX *~ mb hdr->lid;
mac = Im mgmt find mac(idx);
if (mac - - NULI~ {
if (getnext) {
mac = Im mgmt findnext mac(idx);
if (mac =- NUi-l~ {
ret= IRT SUCCESS
mb hdr->ercocie = ER NOSUCHNAME;
goto err exit;
} eise {
ret= IRT SUCCESS;
mb hdr-~ercode = ER GENERIC;
goto err exit;
}

tf (CHK VB(LM VB MSGS)J {
print~("getting stats on mac = %s\r\n", sprint mac addr(&mac->mac addr));
num vians = QUEUi-- LEN(mac->mv q);
Im cvt mac idx(&mac->mac addr, &tmp idx);
~idx = tmp ~dx;
Im cvt idx os(tmp ~d~LM MP MAC, LM NUM ELEM(tmp id~LM MP MAC), &tmp os);
MB wp OS(mb, LM MP MAC PIX, &tmp os);
LM_CLR PORT ADDR(&port addr);
if (mac->port 1- NULL) {
port = mac-~port;
Li~A INIT PORT ADDR(&port addr, tc~>my node, port->port addr.aa shelf + 1, port->port addr.aa slot + 1, port->port addr.aa port + 1);
shelf = port addr.aa shelf;
slot = port addr.aa siot;
port num - port addr.aa port;
MB wp INT'mb, LMi MP SHELF PIX, &shelf);
MB wp~lNT'mb, UM-MP-CMD PIX, &siot);
MB wp INT'rnb, LM MP PORT PIX, 8port num);
MB wp IN'iT'mb, UM MP-NUM ~LANS PIX, &num vlans);
tmp os~en~h = skeof(mac->rnlid bits~;
bcopy(mac->mlid bits, tmp Oc b~ sr~ tmp_os.length);
MB wp OS(mb, LM MP MiLriD BITS PIX, &tmp os);

W0 94/07316 - Pcr/US93/08674 214 ~ D
Im mgmt.c return (ret);
err exit:
retum (ret);
}

Im mgmt get vc ent(msg, getnext) struct AgentMsg *ms~;
Int getnext;
int ret;
struct MB *mb;
struct MBH *mb hdr;
struct Livi VC ENTlDX *idx;
struct LM VC ENT-IDX tmp idx;
Im vc addr t vc addr-Im~vc~t ~ *vc; ~
struct~S tmp os;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr = &mb->head idx - (struct LM VC ENT IDX *) mb hdr->iid;
vc = Im mgmt find vc(id;~);
if (vc =- NULLl {
if (getnext) {
vc = Im mgmt findnext vc(idx);
if (vc =- NULI~ {
ret= !RT SUCCESS;
mb hdr->ercode= ER NOSUCHNAME;
goto err-exit;
} else {
ret= !RT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err exit;

if (CHK VB(LM VB MSGS)) {
p~i~nr(~g~ui"g stats on vc = %s\r\n~, sprint vc addr(&vc->vc addr));

Im_cvt_vc_Idx(&vc->vc addr, &tmp idx);
*idx = tmp idx-Im_cvt idx os(tmp idxLM VC VLAN, LM NUM ELEM(tmp idxLM VC VLAN), &tmp os);
MB wp OS(mb, LM VC VLAN PIX, &tmp os);
Im cvt idx os(tmp idxLM VC MAC, LMi NUM ELEM(tmp id~Livi VC MAC), W O 94/07316 2 1 ~ ~ 1 5 ~ PC~r/US93/08674 Im mgmt.c &tmp os);
MB wp OS(mb LM VC MAC PIX &tmp os);
MB wp INT(mb, LM VC REF CNT PIX &vc-~ref cnt~;
MB wp INT(mb LM VC BID PIX &vc->bW);
retum ~et);
err exit:
return (ret);
}

Im mgmt get pm ent(msg getnext) struct AgentMsg *msg;
int getnext;
int ret;
struct MB *mb;
struct MBH *mb hdr struct LM PM ENT IDX *idx;
struct LM PM ENT IDX tmp idx;
Im mac addr t mac addr;
Im mac t *mac;
Im~port~t *port;
Im port addr t port addr;
struct OS tmp os;
int shelf;
int slot;
int port num;
int num vians;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr = &mb->head;
idx - (struct LM PM ENT IDX *) mb hdr->iid;
port = Im mgmt find port~idx);
ff (port =- NULI~ {
H (getnext) {
port = Im mgmt findnext port(idx);
ff (port =- NULL~ {
ret= IRT SUCCESS;
mb hdr->ercode = ER NOSUCHNAME;
goto err exit;
}

} else {
ret= IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
} goto err_exit;
}

j ~

G2.
Im mgmt.c num vlans = QUEUE LEN(port->pv q);
if (CHK VB(LM VB MSGS)) pri.~ LLillg stats on port 96s\r\n~, sprint port addr(&port->port addr));
Im cvt port idx(&port->port addr, &tmp Idx);
*idx = tmplcix;
port addr- port-~port addr;
LM CLR MAC ADDR(&mac addr);
if (port->mac r= NULL) mac= port->mac;
mac addr= mac->mac_addr;
shelf = port addr.aa shelf + 1;
slot = port addr.aa slot + 1;
port num - port addr.aa port + 1;
MB wp INT'mb,lM PM SHEUr PIX, &shelf);
MB wp INT mb, LM PM-CARD PIX, &slot);
MB wp INT mb, LM-PM PORT PIX, &port num);
MB wp INT mb, LM PM NUM VLANS PIX, &num vlans);
tmp os.leng-h = sizeof(rnac addr) - 2;
bcopy((char *) &mac addr + 2, tmp os.buffer, tmp os.length);
MB wp OS(mb, LM PM MAC PIX, &tmp os);
tmp os.length - sizeof(port->mlid bits);
bcopy(port->mlid bits, tmp o~ hu~erl tmp_os.length);
MB wp OS(mb, LM PM M~D BITS PIX, &tmp os);
return (ret);
err exit:
return (ret);
}

Im_srvc mgmt validate(msg) struct AgentMsg *msg;
{

int ret;
struct MB *mb;
struct MBH *mb hdr;
struct AgentMsg *tx msg;
ret= RT SUCCESS;
tx msg - Im cp mgmt msg(msg);
mb = &tx msg->Body, mb hdr - &mb->head;
switch (mb hdr->ovcode) case LM GLBL OVN:
ret = Im rngmt val glbl(tx msg);
break-case LM AllR ENT OVN:

WO 94/07316 2 1 ~ ~ 1 5 l1 Pcr/uS93/08674 Im mgmt.c ret = Im mgmt val attr ent(tx msg);
break;
case LM PV OVN:
ret=~m mgmt val pv(tx_msg);
break;
case Ll\l NODE ENT OVN: .
ret = ~m mgmt var nocie ent(tx_mss);
break;
case iNi MAC ENT OVN:
ret =~m mgmt val mac ent(tx msg);
break;
case LM MP ENT OVN:
ret=~m mgmt~val mp ent(tx msg);
break;
case LM PM ENT OVN:
ret = Im mgmt~val pm ent(tx msg);
break;
case LM VC ENT OVN:
ret = Im mgmt val vc ent(tx msg);
break;
default:
ret= IRT SUCCESS;
mb hdr->ercode= ER GENERIC;
goto err exit;
break;
}

ret = Im send mgmt rsp(tx msg);
return (ret);
err exit:
rm send mgmt rsp(tx msg);
return (ret);

Im mgmt val attr ent(msg) struct AgentMsg *msg;
int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LM ATTR ENrT IDX *idx;
Im vian t- *vTan; ~
Im vian id t vian id;
tuililT32 mtu ske;
tUlNT32 num mcasts;
tUlNT8 got mtu ske;
tUlNT8 got num mcasts;
SETUP TCB;
ret = RT SUCCESS;

W O 94/07316 PC~r/US93/08674 2 ~
/6s~
Im mgmt.c mb = &msg->Body;
mb hdr= &mb->head;
mtu ske= num mcasts=-1;
Idx = (struct LM ATTR ENT IDX *) mb hdr-> iid;
vian = Im mgmt find vian(l~x);
H (vian =- NUi~ {
} else {
got num mcasts = MB dop(mb, iM NUM MCAST PIX);
got mtu size = MB dop(mb, i M Ml'U SIZE PIX);
num mcasts = got num mcasts ?
i~B cp INT(mb,~M NUi~A MCAST PIX, 8num mcasts): -1;
mtu ske - got mtu ske ?
MB cp INT~mb, i~i NiTU SIZE PIX, &mtu ske): -1;

return (ret);
err exit:
return (ret);

Im mgmt val pv(msg) struct AgentMsg *msg;
{

int ret;
struct MB *mb;
struct MBH *mb hdr;
struct iM PV IDX *~dx;
Im port vlan t *pv;
SETUP TCB, ret= RT SUCCESS;
mb = &msg->Body;
mb hdr = &mb->head;
idx - (struct iM PV IDX *) mb hdr->iid;
pv = Im mgmt find pv(idx);
H (pv == NUil) {
return (ret);
err exit:
retum (ret);

Im mgmt val node ent(msg) ~ t t -A -tM *
int ret;
struct MB *mb;

W O 94/07316 2 1 4 4 1 5 ~ PC~r/US93/08674 ' /~
Im mgmt.c struct MBH *mb hdr;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg-~Body;
mb hdr= &mb-~head;
ret= IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err exit;
retum (ret);
err exit:
return (ret);
}

Im mgmt val mac ent(msg~
struct AgentMsg *msg;
int ret;
struct MB *mb;
struct MBH *mb hdr;
Im mac vlan_t *mv;
SETUP TCB, ret= RT SUCCESS;
mb = &msg->Body;
mb hdr= &mb->head;
return (ret);
err exit:
return (ret);

Im mgmt val glbl(msg) struct AgentMsg *msg;
int ret;
SETUP TCB;
ret = RT SUCCESS;
return (ret);

Irn mgmt val mp ent(msg) { struct ~gentMsg *msg;
int ret;

W O 94/07316 PC~r/US93/08674 4 ~
Im mgmt.c struct MB *mb;
struct MBH *mb hdr;
struct LiVi MP ENT IDX *idx;
struct LiVi MP ENT IDX tmp Wx;
Im mac addr t rnac addr;
Im~mac~t ~*mac; ~
Irn~port t *port;
Im por- addr t port addr;
struct OS tmp os;
int shelf;
int slot;
Int port num;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr = &mb->head;
idx - (struct iNi MP ENT IDX *) mb hdr-~lid;
mac = Im mgmt find mac(idx);
H (mac == NUil~ {
} els~ {
return (ret);
err exit:
return (ret);
}

Im mgmt val pm ent(msg) struct AgentMsg *msg;
{

int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LM PM ENT iDX *idx;
struct LM PM ENT IDX tmp idx;
Im mac addr t mac addr;~
Im~mac~t ~*mac; ~
Im port t *port;
Irn port addr t port addr;
struct OS tmp os;
Int shelf;
int siot;
Int port num;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr= &mb-~head;

~ ~ 4 ~ ~ ~ 4 PCr/US93/08674 ' , . , - i Im mgmt.c idx = (struct i M PM ENT IDX *) mb hdr->iid;
port = Im mgmt find port~idx);
H (port -c NULL~ {
} else {
retum (ret);
err exit:
retum (ret);

Im mgmt_val vc ent(msg) struct AgentMsg *msg;
int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LMi VC ENTlDX *idx;
struct LM VC ENT IDX tmp idx;
Im vc addr t vc addr;
Im~vc~t ~ *vc; ~
struct~S tmp os;
SETUP TCB;
ret= RT SUCCESS;
mb= &msg->Body;
mb hdr = &mb->head;
idx - (struct LM VC ENT IDX *) mb hdr->tid;
vc = Im mgmt ~nd vc(id~);
if (vc =- NUL~ {
} else {
return (ret);
err exit:
retum (ret);

Im srvc mgmt commit(msg) struct AgentMsg *msg;
int ret;
struct MB *mb;
struct MBH *mb hdr;
struct AgentMsg *tx msg;
ret= RT SUCCESS;
tx msg - Im cp mgmt msg(msg);
mb = &tx msg->Body, mb hdr-- &mb->head;

.

214 ~1~ 'l Im mgmt.c switch (mb hdr->ovcode) {
case LM GIBL OVN:
ret=~m mgmt cmt glbl(tx msg);
break;
case LM ATTR ENT OVN:
ret =~m mgmt cmt attr ent(tx msg);
break;
break;
case LM PV OVN:
ret = lm mgmt cmt pv(tx msg);
break;
case LM NODE ENT OVN:
ret = Im mgmt crnt node ent(tx msg);
break;
case LM MAC ENT OVN:
ret = Im mgmt cmt mac ent(tx msg);
break;
case LM MP ENT OVN:
ret = lm mgmt~cmt mp ent(tx msg);
break;
case LM PM ENT OVN:
ret=~m mgmt~cmt pm ent(tx msg);
break;
case LM VC ENT OVN:
ret = lm mgmt cmt vc ent(tx msg);
break;
default:
ret= IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err exit;
break;
ret = Im send mgmt rsp(tx msg);
return (ret);
err exit:
Tm send mgmt rsp(tx msg);
return (ret);
}
Im mgmt cmt glbl(msg) struct AgentMsg *msg;
int ret;
int i;
struct MB *mb;
struct MBH *mb hdr;
struct OS tmp os;
tUlNT32 *dflt mtu ske;
tUlNT32 *dflt~num mcasts;

W O 94/07316 2 ~ 4 ~ PC~r/US93/08674 -~ , .
Im mgmt.c tATMADDR *nac addr bits t *bid bits, bits t *mlid bits;
tUlN-T32 dflt mtu ske_a;
tUlNT32 dflt num mcasts a;
tATMADDR nac addr a;
blts t bld blts a[SlZE BID BITS];
bits t mlid bits a[SlZE ML~D BITS];
SEfUP TCB;
ret= RT SUCCESS;
mb= &msg->Body;
mb hdr= &mb-~head;
dflt mtu size = dflt num mcasts = nac addr =
bid bits = mlid bits - NUUL;
if (MB dop(mb, LM NAC ADDR PIX)) {
MB cp OS(mb, LM NAC ADDR PIX, &tmp os);
if (tmp os.length !- sizeof(nac addr a)) {
ret- IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err exit;
bcopy(tmp og hlrfFer, &nac addr a, sizeof(nac addr a));
nac addr- &nac addr_a;
if (MB dop(mb, LM BID PIX)) {
bzero(bid bits a, sizeof(bid bits a));
MB cp OS(mb, LM BID PIX, &tmp os);
if (tmp os.length > sizeof(bid bits a~) ret- IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err_exit;
bcopy(tmp o~ bl~er, bid bits a, tmp os.length);
bid_bits=-&bid bits a;
if (MB dop(mb, LM DFLT_MTU PIX)) {
MB cp INT(mb,~M DFLT M-TU PIX, &dflt mtu ske a);
dflt mtu size = &dflt mtu size a;
if (MB dop(mb, UM DFLT MCAST PIX)) {
MB cp INT(mb, LM DFLT MCAST PIX, &dflt num mcasts a);
dflt~num mcasts =-&dflt num mcasts a-}
if (MB dop(mb, UM MUD BITS PIX)) ~bzero(mlid bits a, skeof(mlid bits a));
MB cp OS(mb, LM MLID BITS PrX, &tmp os);
K (tmp os.length > sizeof~mlid bits a)) {
ret- IRT SUCCESS;
mb hdr->ercode = ER GENERIC;

Pcr/US93/08674 .

219 ~ Im mgmt.c goto err exit;
bcopy(tmp os.bufier, mlid bits a, tmp os.length);
mlid bits - &mlid bits a;
Im chg glbl cfg(dflt mtu ske, dflt num mcasts, nac addr, bid bilts, ~ rnlTd blts);
return (ret), err exit:
return (ret);
}

Im mgmt cmt attr ent(msg) struct AgentMsg *msg;
int ret;
int tmp ret;
Int a r;~
struct MB *mb;
struct MBH *mb hdr;
struct LM AllR ENT IDX *idx;
qlink t *linl~;
Im mac t *mac;
Im mac vian t *mv;
Im~vian t ~*vian;
Im vlan id t vian id;
tUrNT32 *mtu size;
tUlNT32 *nurn mcasts;
tUlNT32 *dflt mlid;
char *vian name;
tUlNT32 mtu size a;
tUlNT32 num mcasts a;
tUlNT32 dflt mlid a;
char vlan name a[LM MAX VLAN NAME];
int vian name len;
struct OS tmp os;
int chngd;
SETUP TCB;
ret = RT SUCCESS;
chngd -=FALSE;
mb = &msg->Body;
mb hdr = 8mb->head;
a r = MB cmp ix(mb, LM Vi AN PIX, LM VLAN IXO, LM VLAN IXL);
dflt mlid = num mcasts = mtu size = vian name = NULL;
num mcasts a = tcb->dflt num mcasts;

WO 94/07316 ~! ~ 4 ~ 1 ~ 4 PCI~/US93/08674 -Im mgmt.c mtu slze a = tcb->dflt mtu ske;
dflt rnlid a = LM MAXl~Ui~;
tmp os.lenç;th = 3;
,, bcopy(~bob", tmp Oc bl ffer, tmp os.length);
K (MB dop(mb, L-M MLiD PIX)) ~
MB cp INT(mb,~M MliD PIX, &dflt mlid a);
dflt mlid = &dflt mlid a;
}
K (MB dop(mb, LM NUM MCAST PIX)) {
MB-cp INT(mb, LM N-UM MCA-ST PlX &num mcasts a);
nurn mcasts = &num mcasts a;
K (MB dop(mb, LM MTU SIZE PlO {
MB-cp INT(mb, LM MTU STZE PIX, &mtu ske a);
} mtU-size = &mtu s~e a;
K (MB dop(mb, LM VLAN NAME PIX)) {
MB cp OS(mb, LM VL-AN NAME PIX, &tmp os);
K (tmp os.length > sizeof~an name a) -1) {
tmp os.length = sizeof(vian name a) - 1;
} vian_name= &vian name a;
bcopy(tmp os h~ffer, vian name a, tmp os.length);
vian name altmp os.length] = 0;
idx = (struct LM ATTR ENT IDX *) mb hdr->iid;
vian = Im mgmt~find vian(idx);
K (vian =- NULL && a r == MB IXP CREATE) {
Im cvt idx vian(idx->LM VLAN, &~an id)-vian = add van(vian td, mtu size a, num mcasts a, vian name a);
} else if (vian l= NUi L && a r == MB IXP DELETE) {
vian id = vian->vian id;
free vian(van);
vian = NULL;
K (vian l= NULL) {
Im chg van cfg(vian, dflt mlid, num mcasts, mtu ske, vlan name);
K (vian != NULL) {
print vian(vian, 0);
} else ~
ed to add van %d, a r = %d\r\n~, vian id, a r);
return (ret~;
err exit:
return (ret);

W O 94/07316 PC~r/US93/08674 ~4~15'1 ,7~ ~
Im mgmt.c Im mgmt cmt pv(msg) struct AgentMsg *msg;
{
int ret;
int a r;
struct MB *mb;
struct MBH *mb hdr;
struct i M PV iDX *~ix;
Im port t- *port;
Im~vian~t *vian;
Im pore addr t port addr;
Im vian W t vian rd;
tUiNT32 *mlid, tUlNT32 mlid a;
Im port vian t *pv, SETUP 'rCB, ret= RT SUCCESS;
mb = &msg->Body;
mb hdr= &mb->head;
mlid = NUl;
a r = MB cmp k(mb, i M PV Vi~N PIX, iNi PV Vi AN iXO, iM PV Vi AN iXL);
idx = (struct i~ PV IDX *~ mb hdr->iid;
pv = Im mgmt f~nd pv(idx);
if (pv =- NUil && a r == MB IXP CREATE) {
Im cvt idx port(&idx->iM P~i Si-iEU, &port addr);
Im cve idx vian(&idx->i i PV Vi AN, &vian id);
port = FIND PORT(tcb-> port q, &port add~;
vian = FIND VLAN(tcb->vian q, vian id);
if (port == NUil) ~
port = add port(&port addr);
if (vian == NUil) {
vian = add vian(vian id, tcb->dflt mtu ske tcb->dflt num mcasts);
}

pv = add pv(&port addr, vian id, vian->dflt mlid);
if (pv = = NUi L) {
ret= IRT SUCCF-SS;
mb hdr-~ercode = ER GENERIC;
goto err exit;
} else H (pv l= NUil && a r == MB IXP DEi~E) {
free pv(pv);
pv- NULi;
H (pv != NUl) {
H (MB dop(mb, i M PV Mi~D PIX)) {
MB cp INT(mb,~i~PV MLID PIX, &mlid a);

WO 94/07316 2 ~ ~ 4 1 ~ 4` PCI /US93/08674 Im mgmt.c mlid = &mlid a;
} eise {
,, ret= IRT SUCCESS;
mb hdr->ercode= ER GENERIC;
goto err_exit;
if (pv l= NUil) {
} Im_Ch9_pv_cfg(pv, mlid);
return (ret);
err exit:
return (ret);

Im mgmt cmt notie erd(",sg) struct AgentMsg *msg;
int ret;
struct MB *mb;
struct MBH *mb hdr;
Si-TUP TCB;
ret= RT SUCCESS;
mb= &msg->Body;
mb hdr = &mb->head;
ret= !RT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err exit;
return (ret);
err exit:
return (ret);

Im m~mt cmt mac ellt(~"sg) struct AgentMsg *msg;
int ret;
int a r; /* add/removc flag ~/
struct iM MAC ENT IDX tmp Idx;
struct MB *mb;
struct MBH *mb hdr;
struct i M MAC EN-T IDX ~idx;
Im mac addr t mac addr;
Im vian7d t vian id, tUrNT32 *mlid , WO 94/07316 PCr/US93/08674 214~4 Im mgmt.c tUlNT32 mlid a;
Im mac vian t *mv;
Im~mac~t ~ *mac;
Im~port t *port;
Im~vian~t *vian SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr = &mb->head;
mac = NULL;
mlid = NUUL;
idx = (struct LM MAC ENT IDX *) mb hdr->iid;
a r = MB cmp ix(mb, UM iviAC VLAN PIX, UM MAC Vi AN iXO, LM MAC YLAN iXL);
mv = Im mgmt find mv(idx);
K (mv =- NULL && a r == MB IXP CREATE) {
Im cvt ~dx mac(&idx->LM M-AC ADDR, &mac addr);
Im cvt idx vian(&idx->LM MAC VLAN, &vian rd);
mac - FIND MAC(tcb->mac q, &mac addr);
vian = FlND~/LAN(tcb->vian q, vian Id);
K (mac == NULL) {
mac = add mac(&mac addr);
K (vian == NULL) {
vian = add vian(vian ~d, tcb->dflt mtu size, tcb->ciflt num mcasts);
mv = add mv(&mac addr, vian_id, LM_MAX MID, vian->dflt mlid);
} else if (mv l= NULL &-& a_r == iviB IXi' DELETE) {
mac = mv- > mac;
free mv(mv);
mv= NULL;
K (mv != NULL) {
mac= mv->mac;
K (MB dop(mb, LM MAC MUD PDq) {
K (mac == NULL) {
ret= !RT SUCCESS;
mb hdr->ercode= ER GENERIC;
goto err exit;
aiB cp INT(mb, UM MAC MLiD PIX, 8mlld a);
mlid = &mlid a;
}

} else {
ret= IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
CJoto err exit;

WO 94/07316 2 1 4 ~1 1 5 ~ Pcr/us93/o8674 ~72~
Im mgmt.c -137, K (mv I= NULL) {
Im chg mv cfg(mv, mIid);
return (ret);
err exit:
} return (ret);
Im_mgmt c`mt vc ent(msg) struct AgentMsg *msg;
int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LM VC ENTlDX *idx;
struct LM VC ENT IDX tmp idx;
Im vc addr t vc addr;
Im~vc~t ~ *vc; ~
Im bid t *bid;
tUrNT32 *ref cnt;
Im bid t bid a;
tUrNT32 ref cnt a;
struct OS tmp os, SETUP TCB;
ret = RT SUCCESS;
mb = &msg->Body;
mb hdr= &mb->head;
bid - ref cnt= NULL;
idx = (struct LM VC ENT IDX *) mb hdr->iid;
vc = Im mgmt ~nd vc(idx~;
if (vc =- NULL~ {
ret= IRT SUCCESS;
mb hdr->ercode = ER GENERIC;
goto err exit;
Im cvt vc idx(&vc->vc addr, &tmp idx);
*idx = tmp idx;
Im cvt Wx os(tmp id~LM VC Vi~N, LM NUM ELEM(tmp Idx LM VC_VLAN), &tmp os);
if (MB dop(mb, LM VC REF CNT PIO ~
MB-cp INT(mb,~M VC REF CNT PIX, &ref cnt a);
ref cnt = &ref cnt a;
}
if (MB dop(mb, LM VC BID PIX)) {
MB cp INT(mb, LM VC BID PIX, &bid a);
bid - g~bid a;
Im chg vc cfg(w, b~d, ref cnt);

WO 94/07316 PCr/US93/08674 2 ~ 5 11 /7~
Im mgmt.c return (ret);
err exit:
return (ret);
}

Im mgmt cmt pm t:llt(llls~) struct ~gentMsg *msg;
{

Int ret;
struct MB *mb;
struct MBH *mb hdr;
struct LM PM ENT iDX *idx;
struct LM PM EiNT IDX tmp idx;
Im mac addr t mac addr a;
~m mac addr t *mac addr, bits t *mlid bits, bits t mlidbits a[SlZE MLID BITS];
Im port t *port;
Im port addr t port addr;
struct OS ~tmp os;
SETUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr= &mb->head;
mac addr = mlid bits = NUi L;
idx - (struct LM PM ENT IDX *) mb hdr->iid;
port = Im mgmt find port~idx);
if (port =- NUil~ {
ret= !RT SUCCESS;
mb hdr->ercode = ER _ GENERIC;
goto err exit;
if (MB dop(mb, LM PM MAC PIX)) {
LM CLR_MAC ADDR(&mac addr a);
MB-cp OS(mb, LM PM MA~ PIX; &tmp os);
bcopy~mp_os hllffer~ (char *) &mac addr a + 2, tmp os.length);
mac addr - &mac addr a;
if (MB dop(mb, LM Pivi MLiD BITS PIX)) {
MB cp OS(mb,lM FM M~-iD BrTS PIX, &tmp os);
bcopy~mp os.buffer, mild bits a, tmp os.leng~;
mlid bits - 8mltd bits a;
}

if (port l= NULL) {
Im chg port cfy(port, mac addr, mlid bits);
return (ret);

WO 94/07316 ~ 1 ~i l i 5 ~ PCI~/US93/08674 . .
~ , . .
Im mgmt.c -l39 err exit:
return (ret);

Im mgmt cmt mp ent(msg) struct AgentMsg *msg;
int ret;
int a r; /* add/remove flag */
struct MB *mb;
struct MBH *mb hdr;
struct LiAfi MP ENT IDX *idx;
struct LM MP ENT IDX tmp idx;
Im mac addr t mac addr;
Im mac t *mac;
Im~port t *port;
blt~ t *mlid bits;
bits t mlid bits a[SlZi- MLiD BITS];
Im port addr t port addr;
struct OS tmp os;
int shelf;
int siot;
int port num;
Si-TUP TCB;
ret= RT SUCCESS;
mb = &msg->Body;
mb hdr= &mb->head;
mlid bits = NULL;
idx - (struct i M MP ENT IDX *) mb hdr->iid;
a r = MB cmp Ix(mb, LM MP MAC PIX, LM MP MAC iXO, i~fi MP MAC IXL);
rnac = Irn mgrnt find mac(idx~
if (mac =- NUil && a r == MB IXP cREATq {
Im cvt idx mac(&idx->i M MP-MAC, &mac addr);
mac - add mac(&mac a~dr);
if (mac ==l~Ui L) {
ret= IRT SUCCESS;
mb hdr->ercode= ER GENERIC;
goto err exit;

if (mac l= NUi L && a r == MB IXP DEI~TE) {
free mac(mac);
mac = NULL;
if (mac l= NULL) {
if (MB dop(mb, U~A MP MUD BITS P10 {
MB cp Os(mb~lM NiP M~iD BrTS PIX, &tmp os);
bcopy~mp os hl ffer, ml~d bits a, tmp os.lengt~;
mlid bits - &mlid bits a;

P~r/US93/08674 2 1 4 4 1 5 ~ 8 Im m g mt.c H (mac != NUiLL) {
Im_chg mac cfg(mac, mlid bits);
return (ret);
err exit:
return (ret);
}

struct AgentMsg *
Im cp mgmt msg(msg) struct AgentMsg *msg;
{

struct AgentMsg *ret;
int msg len;
msg len = msg->Hdr.Length + ITSZ;
ret - (struct AgentMsg *) Re ~j~ 'sDAAemZero(msg ien);
H (ret == NULL) goto err exit;
bcopy(msg, ret, msg -en);
return (ret);
err exit:
~rash(993, O, O);
}

Im vc t *
Im mgmt find vc(idx) struct L i i'V IDX *idx;
Im vc addr t tmp vc;
Im~vian t ~ *vian;
Im~vc t- *ret;
Si_TUF TCB;
ret = NUI_L;
Im cvt idx vc(idx, &tmp vc);
vian = FIND VLA~-(tci~>vian q, tmp vc.vian id);
H (vian I = N~LL) {
ret = FIND VC(vian->vc q, &tmp vc);
return (ret);

Im port vian t *

WO 94/07316 2 1 4 'I 1 5 ,L PCI/US93108674 -/7~
Im_mgmt.c lm mgmt find pv(idx) struct ~M PV IDX *idx;
Im port vlan t tmp pv;
Im~port~vlan~t *ret;~
SETUP TCB, Im cvt idx pv(idx, &tmp pv);
ret = flND PV(tc~>pv q, &tmp pv);
retum (ret), }

Im mac vlan t *
Im_mgrnt find mv(idx) struct IM MAC ENT IDX *idx;
{
Im mac vian t *ret;
Im~mac~vlan~t tmp mv;
Im~mac~vlan~t *mv,~
Si-TUP TCB, Im cvt idx mv(idx, &tmp mv);
ret = ~iND MV(tcb->mv q, &tmp mv);
return (ret), }

Im mac t *
Im mgrnt find mac(idx) struct LM MP ENT IDX *idx;
{
Im mac t *ret;
Im mac addr t mac addr;
SEl UP ~CB;
Im cvt idx mac(idx->LM MP MAC, &mac addr);
ret = FIND MAC(tcb->mac q, &mac addr~;
} return (ret), Im port t *
Im mgmt find port(idx) { struct ~M_PM_ENT_iDX idx;
Im port t *ret;
Im port addr t port addr;
Si-~TUP TCB;
Im cvt idx port(&idx->LM PM SHEU, &port addr);
ret = FIND PORT(tcb->port q, &port addr);
return (ret), ~.

WO 94/07316 Pcr/US93/08674 21 4 4 ~ 5 4 im mgmt.c }

Im vian t *
Im mgrnt flnd vian(ldx) struct~i ~TTR ENT IDX *idx;
{
Irn vian id t vian id;
Int~ ~ ~ ~; ~
SETUP TCB;
Im cvt idx vian(idx->iM Vi AN, &vian Id);
ret = FiND VLAN(tcb->vlan q, vian id~;
return (ret);

Im vc t *
Im mgmt findnext_vc(idx) { struct LM_VC_ENT_iDX idx;

Im vc addr t tmp vc;
Im vc t *ret; ~
Im~van t *vian-SETUP TCB;
ret= NULL-Im cvt idx vc(idx, &tmp vc);
vian =~li~D VLAN(tcb->vian q, tmp vc.vian W);
K (vian != NDLL) ~
ret = FINDNEXT VC(vian->vc q, &tmp vc);
if (ret == NULL) ~
vian = FINDNEXT VLAN(tcb->vian q, tmp vc.vian id);
ret = FINDNEXT VC(vian->vc q, &tmp vc);

retum (ret);

Im port vian t *
Im mgrnt flnanext pv(idx) struct O~i PV ii)X *idx;
Im port vian t tmp pv;
Im port~vian~t *ret-~
Si~UP TCB, Im cvt idx pv(idx, &tmp pv);
ret = FiND-NEXT PV(tcb-~pv q, &tmp pv);

WO 94/07316 2 1 4 ~ l PCI/US93/08674 .

/oD~ ! !
Im mgmt.c return (ret);
}

Im mac vlan t *
Im mgmt findnext mv(idx) struct l~ iAC ENT IDX *idx;
{

Im mac vian t *ret;
Im~mac~vian~t tmp mv;
Im mac addr t mac addr;
Irn~mac-vian t *mv-~
S~UP TCB, Im cvt idx mv(idx, 8tmp mv);
ret = i~NDiiEXT MV(tcb->mv q, &tmp mv);
return (ret);
}

Im mac t *
Im mgrnt findnext mac(idx) struct ~M MP ~NT IDX *idx;
{
Im_mac t *ret;
Irn mac~addr t mac addr;
SETUP TCB;
Im cvt idx mac(idx->LM MP MAC, &mac addr);
ret - i~NDiiEXT MAC(tcb->rnac q, &mac addr);
return (ret);

Im port t *
Im mgmt findnext port(idx) { struct ~i_PM_i-NT_lDX idx;
Im port t *ret;
Irn por~ addr t port addr;
S~TUP TCB;
Im cvt Idx port(8~dx-~LM PM SHEU, &port addr);
ret = iCND-NEXT PORT(tcb->port q, &port addr);
return (ret);

Im vian t *
Im mgrnt flndnext van(idx) struct ~M ATT~ ENT IDX *idx;
,~ _ _ _ Im vian t *ret;
Im vlan id t vian id;

W O 94/07316 ~ PC~r/US93/08674 .

2~41 Im mgmt.c int i;
SETUP TCB;

Im cvt idx vian(idx->- M Vi AN, &vian Id);
ret - i~NDNEXT ViA~i(tci~>vian q, vran_id);
return (ret);

Im cvt mv idx(mv, idx) Im mac vian t *mv;
struct LM MAC ENT IDX *idx;
{
bzero(idx, sizeof(*idx));
Im cvt mac idx(&mv->mac addr, idx->LM MAC ADDR);
Im cvt vian idx(&mv->vianld, Tdx->LM MAC ViAN);
}
Im cvt pv_Idx(pv, Idx) ~m port vian t *pv;
struct LM PV iDX *idx;
{
bzero(idx, sizeof(*idx));
idx->LM PV SHEU= pv->port addr.aa shelf + 1;
idx->LM PV CARD = pv->port addr.aa slot + 1;
idx->LMi_PV PORT = pv->port addr.aa port + 1;
Im cvt_vian~ldx(&pv->vian id, icix->iM PV ViAN);

Im cvt port idx(port addr, idx) lm port addr t *port addr;
struct LM PM ENT I~X *idx;
{

bzero(idx, ~i ~uf(Ai ix));
idx->LM PM SHEU = port addr->aa shelf + 1;
idx->LM PM CARD = port addr->aa slot + 1;
idx->LM PM PORT = port addr->aa port + 1;
}

Im cvt vc_Idx(vc_addr, idx) lm vc addr t *vc addr;
structlM \)C ENT -iDX *idx;
{
bzero(idx, skeof(*idx));
Im cvt mac idx(&vc addr->mac addr, idx->LM VC MAC);
Im cvt~vian~idx(&vc addr->vian-id, idx->L~lri VC VLAN);

Im_cvt mac idx(mac, idx) Im_rnac addr t *mac;_ WO 94/07316 2 1 4 ~ PCI~/US93/08674 .

im_mgmt.c { struct LM_MP_ENT_iDX *~dx;
int i;
bzero(idx, sk~of(Ai ix));
for (i = ATM FIRST MAC, I < s,k~ " mac addr t), I+ +) {
idx->Wi MP MAC[I - ATM FIRST I~ACl - mac->aa byte[ll;
}

Im cvt vian idx(vian id, Idx) 7m vian id t *vian Id;
struct i~ ATTR ENT IDX *Idx;
bzero(idx, sk~of(~i ix));
idx-> LM Vi AN[LM Vi AN iXL - 1] = *vian id;

/**/
Im cvt Idx mv(idx, mv) struct Li~i MAC ENT IDX *Idx;
Im mac vian t~*mv, Im cvt Idx mac(idx->LM MAC ADDR, &mv->mac addr);
Im cvt idx vian(idx->LM iviAC VLAN, &mv->vian rd);

Im cvt idx pv(idx, pv) struct Li i PV IDX *idx;
Im port vian t *pv;
Im cvt idx port(&idx->LM PV SHELF, &pv->port addr);
Im~cvt~idx~vian(idx-> LM FV ~Ti AN, &pv->vian id~;
}
Im cvt idx vc(idx, vc addr) struct i~i VC ENl~ IDX *idx;
Im vc addr t *vc~addr;
_ Im cvt idx mac(idx->i~ VC MAC, &vc addr->mac addr);
Im cvt idx vian(idx-~W VC VLAN, ~vc addr->vian id);

Im cvt idx port(idx, port) struct L1~i PM ENT IDX *idx;
Im port addr t *port;
SErUP TCB;

~14~1 ~4 Im mgmt.c -14~
LM INIT PORT ADDR(port, tcb-~my node, idx->LM PM SHELi- -1, i~x->LM- PM CARD -1, Idx->LM PM PORT -1);

Im cvt idx mac(idx, mac) stnuct LM MP ENT iDX *idx;
Im mac addr t *mac;
Int l;
LM CLR MAC ADDR(mac);
for~i = A-TM i~RST MAC; i < ,~ ut(i,-, mac addr t); i++) {
mac->aa byte[ir= Idx->LM Mi' MAC[i - ATM ~IRST MAC];

Im cvt idx vian(idx, vian id) struct LM ATTR ENT1DX *idx { Im_vian_id_t vian_ia;
*vian id = idx->LM VLAN[LM VLAN iXL- 1];

Im cvt idx os(idx, len, os) u short *idx;
int len;
struct OS *os;
int j;
os->length = len;
for (i = 0, i < len; i++) {
os->buffer[i] = idx[i];
} }

WO 94/07316 2 ~ 4 ~
-,~
Im util.c ~47.
/* Im util.c * COPYRlGi-iT 1992 ADAi TlVE CORPORATION
* ALL RIGHTS RESERVED
* Des;~ ion;
* <Des; ;;-J~;OII of the generai category of file co n~rl~S>
cAn Oi TlONAL list slllllllldlking the routines In thls fiie>
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcNL~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
#Hdef CERNEL
#include~ipc def.h~
#indude net def.h~
#include <global def.h~
#include <driverh>
i~undef Im init #else /* Hndef CERNEL */
#include <stdint.h>
#include <ITC if.h>
#Include RT H.h>
#include <glo~al def.h>
#include <driver.h>
#include <timer.h>
#include <RT def.h>
#Include <enet H.h>
#include <net def.h>
#include <NA~ shared def.h>
#define ERRLOG printdbg #define prinff printdbg #endH /* Hdef CERNEL */
#incdude ~unipdu.h~
#include ~nnipdus.h~
#include~aitask gl.h #~nclude~sigtask gl.h~
#include ~svctask gl.hU
#incdude svc H.h~
#include~snmp ind.h~
#include~ML if.h~
#indude~wdb H.h~
#include ~q.h~
#Include ~bits.h~
#include ~lm.h~

2144151 Im UtiLc static char hex di~q[] = Yo123456789~hcdefY;
Im es cfg resp t *
Im bul~d es cfg resp(mac, enq, resp len) Im mac t *mac;
tC~GEL~M *enq;
int *resp ien;
Im es cfg resp t *ret;
int~ ~ ~ ret ~en;
int num paddrs;
tPORT CFGELEM *paddr;
qlink t *link;
Im rnac vian t *mv;
Im port t *port;
struct atm addr port addr;
int ~ i;
int mlid;
SETUP TCB;
ret= NULL;
ret len = o;
tf (CHK VB(LM VB MSGS)) {
print~(USending es cfg resp msg to mac %s~r\nY, sprint mac addrT&mac->mac addr));
port = mac->port;
num paddrs=-1;
if (port != NULL) {
for (link = HEAD Q(mac->mv q); link != NULL; link = link->next) {
mv = (Im mac vian t *) link->data;
mlid = mv->mrd printf(Ynum padd;s = 96d, mlid = %d\r\n", num paddrs, mlid);
num paddrs = (num paddrs <= mlid) ? mlid: num paddrs;
}

num paddrs++;
ret len = SIZE LM ES CFG RESP +
~num paddrs- 1~ * skeof~tPORT CFGELEM);
ret = (Im es cfg resp t *) ReqMsgi~lremZero(ret len);
if (ret == NULL) ~ oto err exit;
bzero(ret, ret len);
BUILD UNI flDRm(&ret->lmi hdr, NNI PROTOCOL, NN PDU STATUS RESP, LMr STATUS CONFI-G, LMI GLOBAL CREF TYFE, LMI GLOBAL CREF VALUi~;

W O 94/07316 ~ PC~r/US93/08674 ~'7 , .
Im util.c ret->enq = *enq;
port addr= port->port_addr;
paddr= ret->paddr;
for (i = 0; t < num paddrs; 1++) {
paddr i .af type - iMil PORT ADDR;
paddr i .af port = port addr;
} paddr i .af_port.aa lannum = I;

link= Hi-AD Q(mac->mv q);
for (link = HEAD Q(mac->mv q); link l= NUil; link = link->next) {
mv = (Im mac vian t *) link->data;
mlid = mv->mrd;
paddrlmlid].af type = iMI PORT ADDR;
paddrlmlid].af mid = mv->mid;
if (mv->vian == NUil) ~
paddrlmlid~.af mcasts = 0;
paddrlmlid~.af mtu = 0;
} else ~ -paddr[mlid].af mcasts= mv->vian->num mcasts;
paddrlmlid~.af mtu = mv->vian->mtu size;
paddr[mlid~.af port= port addr;
paddrlmlid~.af port.aa iannum = mv->mlid;
*resp len = ret len;
retum (ret);
err exit:
*resp len = 0;
retum (refl;

Im send mgmt rsp(msg) struct AgentMsg *msg;
Int ret;
Si--TUP TCB;
if (CHK VB(LNi VB MSGS)) {
p~ r( ~ending a mgmt rsp\r\n~);
ret = Sendr uxyrMsg( ~g msg->Body.head.mbsize SNMPA MGMI Gt l ntSf );
} return (ret);

Im send svc rel req(lmi hdr cause) ti~lHDR ~*lmi hdr;

, W O 94/07316 PC~r/US93/08674 .

214~1~4 Im util.c tUlNT32 cause;
int ret;
struct svcK *msg;
tUlNT32 msg ien;
tREL REQ *rel req;
tUlNT8 *rel cause;
tLMlHDR *tx Imi hdr;
tlTC HEADER *itc;
SET~P TCB;
K (CHK VB(i M VB MSGS)) {
pri"L~("sencii"g a svc rel req msg, cause is 96d\r\n", cause);
ret= RT SUCCESS-msg len - SVCIF iDU OFFSET + ~ uf(N~I req);
msg - (struct svcr *) ReqMsgMemZero(msg ren);
if (msg == NULL) {
ret= !RT SUCCESS;
goto err exit;
rel req = (tREL REQ *) & msg->lmi hdr;
tx Imi hdr = &rel req->lmi hdr;
*tx Iml hdr= *Irni hdr;
tx rmi hdr->lh pdu type = SDU RELEASE REQ;
rel cause = (tUlNT8 *) & rel req->lmi cause;
Li~ ADD Fl FM-'~IT(rel cause, LMil RELEASE CAUSE, cause);
ret - Im send svc msg~msg, msg len);
return (ret);
err exit:
return (ret);

Im send svc msg(itc, len) tlTC hEA6ER *itc;
tUlNT32 len;
{ int ret;
SETUP TCB;
if (CHK VB(LMi VB MSGS)) {
iJ~ r('s~l,ding a svc msg\r\n~);
BUILD ITCH((*itc), len - IASZ, TID SVC, 0, EX REQUEST, T-A ML IND RECEIVE, tcb->mytld);
ret= SendMsg(itc~;
return (ret);

WO 94/07316 2 ~ 4 ~ 1 5 ~ PCr/US93/08674 /r~
Im util.c Im send alan cfg(prefix, atm hdr, slot num, active ports, num paddrs, paddrs) Im prefk t pre~K;
Im atm hdr t atm hdr;
tUrNT8- slot num;
tUlNT32 actrve ports;
tUlNT32 num paddrs;
tATMADDR ~padd~, {
Im alan cfg resp t *resp;
Int ret;
int resp len;
int l;
SETUP TCB;
H (CHK VB(LM VB MSGS)) {
p~ (Uselld an aTan cfg msg, prefix = 0x%x, atm hdr = 0x%x\r\n", prefix, atm hdr);
prinff("\tslot num - %d, act ports = %d, num paddrs = %d\r\n", slot num, active ports, num paddrs);
resp len = SIZE LM ALAN CFG RESP + (num paddrs- 1) * sizeof(tATMADDR);
resp = (im alan cfg resp t *) Ro~Ms~'emZero(resp len, 0);
if (resp == NUL~) {
ret = IRT SUCCESS;
goto err exit;
/* Fill in the NNSTATUS RESP fields */
BUILD_UNI HDRm(&resp->lmi hdr, NNI PROTOCOL, NN PDU STATUS RESP, LMr STATUS CONFIG, LMI GLCiBAL CREF TYPE
LMI GLOBAL CREF VALUE~;
_ /* Fill in the ALANCFG ENQ fields */
resp->enq.elem type = ALAN CFG ENQ;
resp->enq.slotid = slot num;
/* Fill in the ALANCFG RESP flelds */
resp->resp.elem type = ALAN CFG RESP;
resp->resp.active ports = active ports;
resp->resp.nac Id = tcb->nac Id;
ATM ADDR C~PY(resp-~resp.nac addr, tcb->nac atm addr);
resp->resp.num paddr= num paddrs;
for (i = o; i < num paddrs; I++) ATM ADDR COPY(resp-~resp ~d~lrs[i]~ paddrs[i]);
ret = ML DataSendNR(&tcb->my aal key, resp, resp len, *((tUlNT32 *) 8 prefK), *((tulNT32 *) & atm hdr));
return (ret);
-W O 94/07316 ' PC~r/US93/08674 .

2~415¦ Im utii.C

err exit:
Tf (resp != NUil) FreeMem(resp);
return (ret);
}
m send es cfg ind(mac) t ~ *mac;
int ret;
Im port t *port;
Im prefix t prefix;
Im atm hdr t atm hdr;
tCFGELEM enq, Im es cfg resp t *resp;
int~ ~ ~ resp len;
tUlNT32 tx shelf;
tUlNT32 tx slot;
tUlNT32 tx port;
tUlNT32 tx vci;
SETUP TCB;
if (CHK VB(i M VB MSGS)) {
print~("sending es cfg ind to mac %s\r\nY, sprint mac addr¦&mac->mac addr));
ret= RT SUCCESS;
port = mac->port;
if (port == NUil) {
ret= IRT SUCCESS;
goto err exit;
}

bzero(&enq, sizeof(enq));
tx shelf = port->port addr.aa shelf;
tx slot = port->port addr.aa slot;
tx port = port->port addr.aa port-tx vci = SHEi F SLOT PORT TO VClm(NN SIG VCI, tx shelf, tx slot, tx port);
enq.af type= LMI CONFIG ENQ;
enq.af version = LMI VERSrON;
enq.af_my address- mac->mac addr;
resp - Imbuild es cfg resp(mac, &enq, 8resp ien);
if (resp =- NUi~
goto err exit;
resp->lmi type spec = LMI STATUS IND;
BUILD ATM HDR(&atm hdr, b~ vci);
BUlLi~ UCAST PREFlXr&prefix, tx shelf, tx slot, tx port);

W O 94/07316 2 1 ~ 4 1 5 4 PC~r/US93/08674 /~ ~ r - 7 Im util.c -153' ret = Im send es cfg resp(prefix, atm hdr, resp, resp ien);
return (ret); ~ ~
err exit:
return (ret);
}

Im send es cfg resp(prefix, atm hdr, resp, resp ien) Im prefix~t ~prefix;
Im atm hdr t atm hdr;
I ~ f ~ t * -int ret;
SETUP TCB;
H (CHK VB(Livi VB MSGS)) {
pri"l~( ~ending es cfg resp, prefk = Ox%x, atm hdr = Ox%x\r\n, prefK, atm hdr);
if (resp == NULL) {
goto err exit;
ret = ML DataSendNR(&tcb->my aal key, resp, resp len, *((tUlNT32 *) & prefix), ~((tUlN~32 *) & atm hdr));
return (ret);
err exit:
if (CHK VB(LM VB ERRS)) {
printf("Couldn't send a null aal msg\n");
return (-1);
send mcast cfg0 {
int ret;
}

Im tcb t *
Im~init~
Im tcb t *ret;
int err code;
tUlNT32 1~
int Im crt cfgO;
struct wdb msg *wmsg;
Im glbl cfg key t key;
ret = (Im tcb t *) malloc(SlZE LM TCB);
if (ret =- NUIL) W O 94/07316 . PC~r/US93/08674 21 4 ~15 ~1 Im utll.c goto err exit;
sPtr~ -'.alP(ret);
bzero(ret ;,~ f(~t));
ret-~cur bid = 0;
ret-~my node = MHW GetNodeNumberO;
ret-~my~shelf = MHW GetShelflNumberO;
ret-~my slot = MHW hPtslQtldo bzero(&ret->port tmplt sizeof(ret->port tmplt));
ret->port tmpltaa type = MT PORT;
ret->port tmplt.aa country = I~SA;
ret->port~tmplt.aa~node = ret->my node;
ret->port~tmplt.aa~shelf = ret->my shelf;
ret->tmr blk = Timerlnit(1) Livi INIT PORT ADDR(&ret->nac atm addr ret->my node ret->my shelf ret-~my slot 0);
ret-~dflt mtu size = iM DFLT MTU SIZE;
ret-~dflt~nurn mcasts = LM DFLT NUM MCASTS;
ret-~verbose - Li~i VB ALi ret-~mac q = &ret-~mac queue;
ret-~port q = &ret->port queue;
ret-~vian~q = &ret->vian~queue;
ret->mv q = &ret->mv queue;
ret-~pv q = &ret-~pv queue;
ret-~vc q = &ret->vc queue;
init q'ret->mac q);
init q ret->port q);
init q ret->vian~q);
init~q ret-~mv c);
init q ret-~pv q;
init q;ret-~vc q;;
/* throw away the 0th bid as per jlb's eco"ln,ecidlioll */
bits get bit(ret-~bid bits SIZE BID BITS);
err code = ML SAP Create(LM START VCI LA/i END VCI iNi AAL SID
&ret-~my aal key);
~ifdef UNIX
GetTid(&ret-~mytid);
#else /* Hdef UNIX */
ret-~mytid.Generic = TID i- M;
ret-~mytid.ll,~t-dnce= i-M INSTANCE;
#endif /* Hdef UNIX */
GetPid (&ret- ~ mypid);
ret-~do cfg wrts = TRUE;
key.tag - GLBL CFG t<EY;
wmsg = wdb send fetch wait(&key sizeof(key));

~ =

WO 94/07316 2 1 q ~ PCr/US93/08674 /~
Im util.c ~55 ff (wmsg = = NULL I I wdb get ercode(wmsg) 15 O) {
Im Wudge data initO;
} else {
ret-~do cfg wr~s = FALSE;
wdb send startup queries~l" crt c~g);
} ret->do_cfg_wrts - TRUE;
SendPro~yCheckln(MHW GetCardTypeO, MHW ~et~'otldO);
return (ret);
err exit:
return (NULL);
}

Im mac_t *
add mac(mac addr) Im mac addr t *mac addr-Im mac t *ret;qlink t *link;
Im mac t *tmp;
SETUP TCB;
ff (CHK VB(LM VB TERSE)) {
p~illL~(`addi"g mac addr %s\r\na, sprint mac addr(mac addr));
mac addr->aa type = MT MAC;
ret - FIND MAC(tcb->mac q, mac addr);
if (ret != NULL) return (ret);
ret = (Im mac t *) malloc(SlZE LM MAC);
ff (ret =--NuLI) goto err exit;
bzero(ret, SIZE LM MAC);
ret->mac addr- *mac addr;
ret->mac addr.aa type - MT MAC;
ret->port- NULi, ret->mv q = &ret->mv queue;
init q(ret->mv q);
init~qlink(&ret->mac iink, ret);
ATCH MAC MV Q(tcb->mv q, ret);
PUTQ SoRTED MAC(&ret->mac link, tcb->mac q);
Im wrt mac cfg¦ret, NULL);
return ~ret);
err exit:
Crash(999, O, O);
-PC~r/US93/08674 214 415 l Im Util.c }

Im_port t *
add port(port addr) Im port addr t *port addr;
Im port t *ret;
SETUP TCB;
port addr->aa type = MT PORT;
port~addr->aa~country= USA;
H (CHK VB(L M VB TERSE)) ~
pli~d~( ~dd:,lg port %s\r\n", sprint port addr(port addr));
ret = FIND PORT(tcb->port q, port addr);
if (ret l= N~LL) return (ret);
ret = (Im port t *) malloc(SlZE LM PORT);
H (ret == NUl L) ~oto err exit;
bzero(ret, SIZE iM PORT);
ret->port addr- *port addr;
ret->port addr.aa type - MT PORT;
ret->port addr.aa lannum = O;
ret-> mac = NULI ~
ret->pv q = &ret->pv queue;
Init q(ret->pv_q);
init~qlink(&ret->port iink, ret);
ATCH PORT PV Q(tcb->pv_q, ret);
PUTQ SORTED PORT(&ret-> port link, tcb-> port q);
Im_wrt port cfg~ret);
return Tret);
err exit:
Crash(998, 0, 0);
}

Im vian t *
add ~an(vlan id, mtu, num mcasts, name) Im vlan id t vian id;
Int~ ~ ~ mtu;
int num mcasts;
char *name;
{ Im vlan t *ret-int~ ~ i;

W O 94/07316 ~ PC~r/US93/08674 -/9~
Im util.c Si-TUP TCB;
if (CHK VB(W VB TERSE)) {
prl"L~( ~d ii"g vian %d, mtu = %d, num mcasts = %d, name = %s\r\n-, vian id, mtu, num mcasts, name);
ret = FIND VLAN(tcb->vian q, vian id);
if (ret l= N~LL) return (ret);
ret = (Im vian t *) mailoc(SlZE LM VLAN);
if (ret =- NULI) goto err exit;
bzero(ret, SIZE UM VLAN);
ret->vian id = vian id;
ret->mtu~size = mtu;
ret->num mcasts = 0;
ret->dflt mlid = LM MAX MUD
strcpy(ret-?vian name, name);
ret->mv q = &ret->mv queue;
ret->pv q = &ret->pv queue;
ret->vc q = &ret->vc queue;
ret->free vc q = &ret->free vc queue;
init q ret->rnv q); ~ ~
init~q ret->pv q);
init q ret->vc q);
init~q ret->free vc q);
init qlink(&ret->vian iink, refl;
chg num vcs(ret, num mcasts);
ATCH VLAN MV Q(tcb->mv q, ret);
ATCH VLAN PV Q(tcb->pv q, ret);
PUTQ SORTED VLAN(&ret->vian link, tcb->vian q);
Im chg vlan cfg(ret, &ret->dflt mrd, NUil NULL, NUU );
return ~et); ~
err exit:
~rash(997, 0, 0);
}

Im vc t *
ç1et free vc(vian) Im_vian_t *vian;
Im vc t *ret;
qlink t *link;
ret = NUUL;

WO 94/07316 Pcr/us93/o8674 5 ~ ~96 Im_util.c -lS8 link= HEAD Q(vlan->free vc q);
if (link == NULL) goto err exit;
ret = (Im vc t *) link->data;
rmqQink), PUTQ SORTED VC(link, vlan->vc q);
retum~ret);
err exit:
return (NULL);

Im vc t *
add vc(vc addr) { Im_vc_addr_t vc_addr;
Im vc t *ret;
Irn~vlan t *vlan;
SETUP ~rCB;
if (CHK VB(LM VB TERSE)) ~
pri"l~( add;"g vc %s\r\n, sprint vc addr(vc addr));
ret= NULL;
vlan = FIND VLAN(tcb->vian q, vc addr->vian id);
if (vlan == NULL) ~oto err exit;
ret = FIND VC(vlan->vc q, vc addr);
if (ret l= NilLL) return (ret);
ret = get free vc(vlan);
if (ret =- NULL) goto err exit;
ret->vc addr= *vc addr;
ret->ref~cnt = 0;
return (ret);
err exit:
return (NULL);
}

chg num vcs(vlan, num vcs) Im vlan t *vian- ~
tlNT32 num vcs;
{

WO~4/07316 21~ PCI/US-3/08674 ~97 Im util.c int ret;
int delta;
Int i;
qlink t *link;
qlink t *next;
Im vc t *vc;
Int ~ on vc q;
ret = O;
delta = num vcs-vian->num mcasts;
if (delta < O) {
on vc q = FALSE;
link= HEAD Q(vlan->free vc q);
for (i = O; i > delta; i-) {
if (link =z NUi L) {
if (on vc q) break link= HEAD Q(vian->vc q);
on vc q = TRUE;
}

if (link == NULL) break;
next = link->next;
vc = (Im vc t *) link->data;
free vc(vc);
ret;
link= next;
} else if (delta > O) {
for (i = O; i < delta; i++) {
add free vc(vian);
ret+ +;
}
}

vian->num mcasts = num vcs;
return (ret), }

Im vc t *
add free vc(vlan) Im vian t *vian;
{

Im vc t *ret;
Im mac addr t mac addr;
Im bid t bid;
SETUi' TCB;
bid = bits get bit(tcb-~bid bits, SIZE BID BITS);
if (bid =5 -1) goto err exit;

2 1 ~ 9~ ~
Im util.c H (CHK VB(LM VB TERSE)) {
printF("getting a free mcast vc for vian %s, bid = %d\r\n~, sprint vlan id(&vian->vlan id), bid);
ret = (Im vc t *) malloc(SlZE LM VC);
H (ret =- NULL) goto err exit;
bzero(ret, SIZE LM VC);
LM CLR MAC ADDR(&mac addr);
LM INIT VC ADDR(&ret->vc addr, vian->vlan id, &mac addr);
ret->bid - b~d;
ret->vlan = vlan;
init qlink(8~ret->vc link, ret);
init qlink(&ret->vlan link, ret);
PuTQ SORTED VC~&ret->vc link, tcb->vc q);
PUTQ SORTED VC(&ret->vlan link, vlan->~ree vc q);
return (ret);
err exit:
Crash(994, 0, o);
}

Im_port vlan t *
add pv~port addr, vian id, mlid) Im port addr t *port addr;
Im vian id t vian id;
Irn mlid~t~ mlid-Im port vlan t tmp;Im~port~vian~t *ret;
Im~port~t ~*port;
Irn~vlan~t *vlan;
SETUP ~CB;
H (CHK VB(LM VB TERSE)) {
plintr(~dding pv, port addr = %s, vlan = %d, mlid = %d\r\n~, sprint port addr~port addr), vian id, mlid);
tmp.vlan id = ~llan id;
tmp.port~addr= *port addr;
ret = Fli~D PV(tcb->pv q, &tmp) H (ret l= N~LL) return (ret);
ret = (Im port vlan t *) malloc(SlZE LM PORT VLAN);
if (ret =- NULL) goto err exit;

W O 94/07316 ~ 1 4 ~ 1 5 ~ PC~r/US93/08674 /9~
Im util.c bzero(ret, SIZE LM PORT VLAN);
ret->port addr= *port addr;
ret->~/lan id = vlan id;
ret->port - NULL-ret->vlan = NULL, ret->mlid = mlld;
init qlink(&ret->pv link, ret);
init qlink(&ret->port link, ret);
init qlink(&ret->vlan iink, ret);
ATCH PV VLAN Q(tcb->vlan q, ret);
ATCH PV PORT Q(tcb->port q, ret);
PUTQ SORTED PV(&ret-> pvlink, tcb-> pv q);
Im wrt pv cfg(ret);
return ~ret)~
err_exit:
Crash(996, 0, O);

Im mac vlan t *
add mv~mac addr, vlan id, mid, mlid) Im mac addr t *mac addr;
Im vlan id t vlan id, int mid;
Im mlid t mlid;
Im mac vlan t tmp;
Im mac~vlan~t *ret;
SETUP TCB, if (CHK VB(LM VB TERSE)) {
pri.,U("addi.,g mv, mac addr = %s, vlan = %d, mid = %d, mlid = %d\r\n~, sprint mac addr(mac addr), vlan id, mid, mlid);
tmp.mac addr= *mac addr;
tmp.vlan~id = vlan id;
ret = FIND MV(tcb-~mv q, &tmp);
H (ret l= N[hL) retum (ret);
ret = ~m mac vlan t *) malloc(SlZE LM MAC VLAN);
H (ret =- NUII) ~oto err exit;
bzero(ret, SIZE LM MAC VLAN);
ret->mac addr= *mac addr;
ret->vlan~id = vlan Td;
ret->mac = NULL;
-W O 94/07316 P~r/US93/08674 214 41~ ll Im ut~il.

ret->vian= NUil;
ret->mid = mid;
ret->mlid = mlid;
init qlink(&ret->mv link, ret);
init qlink(&ret->mac link, ret);
init qlink(8ret->~anlink, ret);
ATCH MV VLAN Q(tcb->vian q, ret);
ATCH MV MAC Q(tcb->mac q, ret);
PUTQ SORTED MV(&ret->mv link, tcb->mv q);
Im chg mv cfg~ret, &ret->mlld~;
return (ret);
err exit:
Crash(995, 0, 0);

free tcb(tcb) Im tcb t *tcb;
if (tcb l= NUil) {
FREE VLAN Q(tcb->vian q);
FREE MAC Q(tcb->mac q);
FREE PORT Q(tcb->port q);
FREE VC QTtcb->vc q);
FREE MV Q(tcb->mv q);
FREE PV Q(tcb->pv q);
Im rrn glb-l cfg0;
free(tcb);
}

free mac(mac) Im mac t *mac;
SETUP TCB;
H (mac != NUil) {
if (CHK VB(i M VB TERSE)) {
prl,~ eing mac addr = %s~r\n~, sprint mac addr(&mac->mac addr));
Im rm mac cfg(mac);
rmq(&rnac->mac link);
FREE MY Q(mac->mv q);
Im send es cfg ind(mac);
H ~mac->por~ !- NULL) {
mac->port->mac= NULL;
mac->port= NULL;

WO 94/07316 ~ 1 4 4 1 5 ~ PCr/US93/08674 ~0 Im util.c ~63 } free(mac);
return (NULL);
~ }
free vian(vian) Im vlan t *vian;
SETUP_ TCB;
H (vian l= NULL) {
H (CHK VB(LM VB TERSE)){
pr3n1~ ee3~19 vian %s\r\n~, sprint vian id(&vian->vian id));
Im rm vian cfg(vian);
rmq(&vian->vian link);
FREE PV Q(vian-~pv q);
FREE MV Q(vian->mv q);
FREE VC Q(vian->vc q);
FREE VC Q(vian-~free vc q);
bits free bit(van-~dflt=ml~d, tcb-~mlid bits, SIZE ML-iD BITS);
free~vian~
return (NULL);

free vc(vc) Im vc t *vc;
SETUP TCB;
if (vc l= NULL) {
if (CHK VB(LM VB TERSE)){
p-il-1r(`i~ei.-~ vc %s\r\n~, sprint_vc_addr(&vc->vc_addr));
Im rm vc cfg(vc);
rmq(&vc->vc link);
rmq(&vc->vian link);
vc->vian = NI~IL
bits free bit(vc->b~d, tcb-~bid bits, SIZE BID BiTS);
free~vc);~
} return (NULL);

free port(port) Im port t *port;

W O 94/07316 PC~r/US93/08674 5 ~ ~
Im util.C

SETUP TCB;
if (port l= NULL) {
if (CHK VB(LM VB TERSE)){
ill~( "~ei"g port addr = %s\r\n~, sprint port addr(&port->port addr));
Im rm port cfg(port);
rmq(&port->port link);
if (port->mac l= NULL) {
port->mac->port= NULL;
port->mac= NULL;
FREE PV Q(port->pv q);
free(port);
return (NULL);
}

free port pv(pv) Im port vlan t *pv;
Im port t *port;
If (pv l= NULL) ~
rmq(&pv->port link);
port = pv->port;
if (port l= NULL) {
bits free bit(pv->mlid, port->mlid bits, SIZE MLID_BITS);
pv->port = NULL;
return (NULL);
}

free vlan pv(pv) { Im_port_vlan t *pv;
if (pv I = NULL) {
rmq(&pv->vlan link);
pv->vlan = NULL;
return (NULL);
}

free pv(pv) Im port vlan t *pv;
SETUP TCB;

WO 94/07316 ~ PCI/US93/08674 ~4f i,, ~ . .. -Im util.c ~65 if (pv != NULL) {
H (CHK VB(LM VB TERSE)){
p.illl~ ei ,g pv, port addr = %s, vlan = %d, mlid = %d\r\n, sprint port addr~&pv->port addr), pv->vlan id, pv-~mlid);
Im rm pv cfg(pv);
rmq(&pv->pv link);
free vlan pv(pv);
free~port~pv(pv);
free~pv);
return (NUU );
}

free mac mv(mv) Im mac vlan t *mv;
if (mv != NULL) {
if (mv->mac != NUUL) {
rmq(&mv->mac link);
bits free bit(mv->mlid, mv->mac->mlid bits, SIZE MUD BITS);
mv->mac= NULL
} }
return (NULL);

free vlan mv(mv) Im mac vlan t *mv;

{

if(mvl=NUU){
if (mv->vlan != NULL) {
rmq(&mv->vlan link);
mv->vlan = NULL;
}
return (NUUL);

free mv(mv) Irn mac vlan t *mv;
{

SETUP TCB;
H (mv != NUUL) {
if (CHK VB(LM VB TERSE)){
p-illlf( ,.~,e;ng mv, mac addr = %s, vlan = %d\r\n~, PC~r/US93/08674 .

21 ~ 11 5 1~ Im util.c ~66 ~prtnt mac addr(&mv->mac addr), mv->vian id);
Im rm mv cfg(mv);
H rmv->mac I= NUi L) Im send es cfg ind(mv->mac);
rmq(&mv->mv iink~;
free mac mv(mv);
free~vian~mv(mv~;
free~mv);~
return (NUi L);
}

free mac port(mac, port) Im mac t *mac;
Irn port t *port;
H (mac != NUil) mac->port= NULL;
If (port != NULL) port->mac = NUi L;
return (NULL);
}

chk port mlid(port, mlid) Im port t *port;
Irn mlid t mlid-int ret;
ret = bits tst bit(mlid, port->mlid bits, SIZE iviLiD BITS);
return (ret~; ~
}

chk mac mlid(mac, mlid) Im mac t *mac-Im mlid t mlid;
{

int ret;
ret = bits tst bit(mlid, mac->mlid bits, SlZi MUD BITS);
retum (ret~; ~
}

Im mac t *
cmp mac(mac, mac addr) Irn mac t *mac;
Irn~mac~addr t *mac addr;
H (cmp mac addr(&mac-~mac addr, mac addr) == O) W O 94/07316 2 I 4 415 4 PC~r/US93/08674 .

Im_util.c return (mac);
} retum (NUil);

Im mac t *
crnpnext mac(mac, mac addr) Im mac t *rnac;
Im mac addr t *mac addr;
{
int ret;
ret = cmp mac addr(&mac->mac addr, mac addr);
if (ret >= o) return (mac);
return (NUil);

Im port t *
cmp port(port, port addr) Im port t *port;
Im port addr t *port addr;
K (cmp port addr(&port->port addr, port addr) =z O) return (port);
return (NUil);

Im port t *
c~"pn~xt port(port, port addr) Im port t *port; ~
Im port addr t *port addr;
int ret;
ret = cmp port addr(&port->port addr port addr)-if (ret >= o) ~ - ~ _ return (port);
retum (NUil);

Im vian t *
cmp vian(~/1an, vian Id) Im vian t *vian-Im vian id t vian id;
if (vian->vian id == vlan id) return (vlan);
return (NUiL);

WO 94/07316 PCI~/US93/08674 214~15q ~6 Im util.c }

Im vian t *
cmpnext vian(vian, vian id) Im vian t *vian- ~
Im vian id t vian id;
Int ret;
ret = cmp vian id(&vian->vian id, &vian id);
if (ret >= O) return (vian);
} return (NUil);

Im vc t *
cmp vc(vc, vc addr) Im vc t *vc Im vc addr t *vc addr-N (cmp vc_addr(&vc->vc addr, vc addr) == O) return (vc) return (NUil), }

Im vc t *
cmpnext vc(vc, vc addr) Im vc t *vc Im vc addr t *vc addr;
{

int ret;
ret = cmp vc addr(&vc->vc addr, vc addr);
if (ret >= O) ~
return (vc);
return (NUil);

Im mac vian t *
cmp mv(mv, tst) Im mac vian t *mv;
Im~mac~vian~t *tst {
if (cmp mac addr(&mv->mac addr, &tst->mac addr) == O &&
cmp vian id(&mv->vian Id, &tst->vian id) -= O) return (mv~
return (NUil);
}

-W O 94/07316 2 ~ PC~r/US93/08674 ~f Im util.c -16~
Im mac vian t *
c""Jne,~t mv~mv tst) Im mac vian t *mv;
Im mac vian t *tst;
Int ret;
~ret = cmp mac addr(&mv->mac addr &tst->mac addr);
return (mv);
if (ret == O) {
ret = cmp vian id(&mv->vian id &tst->vian id);
if (ret >= O) return (mv);
} retum (NUil);

Im mac vlan t *
crnp mlrd(mv mlid) Im mac vian t *mv-{ Im_mlid_t mlid;
if (mv->mlid == mlid) return (mv);
return (NUil);
}

Im mac vian t *
cr"~Jne,tt mlid(mv mlid) Im mac vian t *mv-{ Im_mlid_t mlid;
int ret;
if (mv->mlid >= mlid) return (mv);
return (NUil);

Im port vian t *
cmp pvlpv t-st) Im port vian t *pv;
Im port vian t *tst;
if (cmp port addr(&pv->port addr &tst->port addr) == O &&
cmp vian id(&pv->vian id &tst->vian id) -= O) return (pv~;
return (NUil);

2 1 ~
Im util.c ~70-lm port vlan t *
cmpnext pv~pv, tst) Im port vian t *pv;
Im port vian t *tst;
_ Int ret;
ret = cmp port addr(&pv-~port addr, &tst->port addr);
if (ret > O) return (pv);
ret - cmp vian id(&pv->vian id, &tst->vian id);
if (ret >= O) return (pv);
return (NULL);
}

atch mac port(mac, port) Im mac t *mac;
Im port t *port;
mac->port = port;
port->mac = mac;
return (NULL);
}

atch port pv(pv, port) Irn port vian t *pv;
Im port_t *port;
int tst;
if (cmp port addr(&pv->port addr, &port->port_addr) == O) {
PUT~ S~iRTED PV(&pv->port -iink, port->pv q);
pv->port = port;
if (pv->mlid >= LM_MAX_MIJD 1 1 bHs tst bH(pv->mlid, port->mlid bits, SIZE MLiD BITS)) {
pv->mlld = bHs_get bH(port->m~id bHs, SIZE MUD BITS)-p,i"l~ placin~ pv rnlid %d with %d\r\n~, UM lUiAX MUD, pv->miW);
} else {
bits alloc bH(pv->mlid, port->mlid bHs, SIZE_MLID BITS);
}

return (NUU );
}

WO 94/07316 2 ~ I 5 ~ Pcr/US93/08674 ~ , Im util.c atch vian pv(pv, vian) Im port vlan t *pv;
Im vian~t ~*vian;
K (cmp vian id(&pv->vian id, &vian->vian id) == O) {
PUl~ S~5RTED PV(&pv->vian link, vian->pv q);
pv->vran = vian, }
} retum (NUil);

atch mac mv(mv, mac) Im mac vian t *mv;
Im_mac t *mac;
if (cmp mac addr(&mv->mac addr, &mac->mac addr) == O) {
PUT~ S~RTED MV(&mv->mac link, mac->mv q);
mv->mac= mac;
if (mv->mlid >= i M MAX MUD 1 1 bits tst bit(mv->mlid, rnac->mlid bits, SIZE MUD BITS)) {
mv-~mTid = bits get bit(mac->mTid bits, SIZE Mi lD BITS);
pdlllr(~l~placin5i mv rnl~d %d with %d~r\n", i M MAX=Mi iD, mv->mlid);
} else {
bits alloc bit(mv-~mlid, mac->mlid bits, STZE MiiD BITS);
}

return (NUil);

atch vlan mv(mv, vian) Im mac vian t *mv;
Im~vian t ~*vlan;
if (cmp vian ~d(&mv->vian Id, &vian->vian id) == O) {
PUT~ S~5RTED MV(&mv-~vian link, vian->mv q);
mv->vian = vian;
i~ (mv->mid >= i M MAX MID) {
mv->mid = bits get br(vian->mid bits, SIZE MID BITS);
return (NUil);
}

atch pv port(port, pv) Im port t *port;
Im port vian t *pv;
retum (atch port_pv(pv, port));

WO 94/07316 PCI'/US93/08674 '~
1$1 Im util.c atch pv vian(vian, pv) Im vran t *vlan;
Im_port vian t *pv;
retum (atch vlan pv(pv, vlan));

atch mv mac(mac, mv) Im mac t *mac;
Im~mac~vian t *mv;
return (atch_mac_mv(mv, mac));

atch mv vian(vlan, mv) Irn vian t *vlan;
Im~mac vian t *mv;
return (atch vian mv(mv, vlan));

cmp port addr(p1, p2) Im port addr t *p1;
Im port addr t *p2;
int ret;
ret = ATM ADDR EQ(*p1, *p2) ? 0:
ATM ADDR GT(*p1 , *p2) ? 1: -1 ;
return (ret);
}

cmp vian id(v1, v2) Irn vian id t *v1 I ~ i -id-t * 2 int ret;
ret = (*v1 == *v2) ? 0:
*v1 > *v2 ? 1: -1;
return (ret);
}

cmp mac addr(m1, m2) Im mac addr t *m1-Irn mac addr t *m2, int ret;

-WO 94/07316 2 ~ PCI`/US93/08674 Im util.c `~ ' ret = ATM ADDR EQ(*m1, *m2) ? 0:
ATM A~SDR GT(*m1, *m2) ? 1: -1;
retum (ret);

cmp vc addr(vcl, vc2) Im vc addr t *vc1;
Im vc addr t *vc2;
{
int ret;
ret = cmp mac addr(&vc1->mac addr, &vc2-~mac addr);
if (ret == O) ret = cmp vian id(&vc1->vian id, &vc2->vian id);
} return (ret);

cmp pv addr(pv1, pv2) Irn port vian t *pv1;
Im~port vian t *pv2;
int ret;
ret = cmp port addr(&pv1->port addr, &pv2->port addr);
if (ret == O) ret = cmp vian id(&pv1->vian id, &pv2->vian id);
return (ret);

cmp mv addr(mv1, mv2) Im mac vian t *mv1;
Im~mac~vian~t *mv2;
int ret;
ret = cmp mac addr(&mv1->mac addr, &mv2->mac addr);
if (ret == O) ret = cmp vian id(&mv1->vian id, &mv2->vian id);
} retum (ret);

Im tiUp port dflts(port, mac) Im port t *port;
Im rnac t *mac;
qlink t *link;
Im port vian t *pv;
for (link = Hi--AD Q(port->pv q); link l= NUil, Iink = link->next) {

WO 94/07316 . PCI`/US93/08674 .

214~ Im util.c pv = (Im port vian t *) link->data;
add mv(~mac->mac addr, pv->vian id, W MAX MID, pv->mlid);
}

Im kiudge_data_lnitO
Im port addr t port addr;
Im port t *port;
int i;
int J;
Int k;
Int min slot;
int max slot;
int min port;
int max port;
int min vian;
int max vian;
Si-TUP TCB;
min slot = o max slot= ;5;
min port = 0;
max port = 5;
min vian = 1-max vian = 1;

i M INIT PORT ADDR(&port addr. tcb->my node, tcb->my shelf, min slot, min port);
for (j = max slot; j >= min_slot; J-) {
if ~ == tcb->my slot) {
port addr.aa slot= j;
port addr.aa~port= min port;
add port(&port addr);
continue;
port addr.aa siot = j;
for (r= max port; I >= min port; i-) {
port addr.aa port= i;
add port(&port addr);
} }
for (i - max vian- i >- min vian; i-) {
add vian~, tcii->dflt mtu size, tcb-~dflt num mcasts, ~bob~);
} ..
LM INIT PORT ADDR(&port addr, tcb->my node, tcb->my shelf, min slot.

.~J3 .
Im util.c ~75-min port)-for (k = max vian; k >= min vian; k-) {
for a = max slot; J >= min slot; J-) {
if a == tcb-~my slot) {
port addr.aa slot = I;
port addr.aa port= min port;
add pv(&port addr, k, i~ I~AX MLiD);
con~nue;
port addr.aa slot = I;
for ~= max port; i >= min port; i-) {
port addr.aa port= I
add pv(&port addr, k, LM MAX Mi iD);

} }
Im wrt ~Ibl cf~O;
i-t t-b(t -b O) qpsc mac(link1, link2) qlink t *link1;
qlink t *link2;
int ret;
Im mac t *mac1;
Im mac t *mac2;
mac1 = (Im mac t *) link1-> data;
mac2 = (Im mac t *) link2->data;
ret = cmp mac addr(&mac1->mac addr, &mac2-~mac addr);
return (ret), }

qpsc port(iink1, link2) qlink t *link1;
qlink t *link2;
int ret;
Im port t *port1;
Im port t *port2;
port1 = (im port t *) link1->data;
port2 = (Im port t *) link2->data;
ret = cmp port addr(&port1->port addr, &port2->port addr);
} return (ret);

WO 94/07316 PCI'/US93/08674 .

2 ~ 4 ~ Im utii C

qpsc vian(linkl, link2) qlrnk t *link1;
qllni< t *link2;
int ret;
Im vian t *vianl;
Im~vian~t *van2;
vian1 = tm vian t *) link1->data;
vian2 = tim~vian t *) link2->data;
ret = cmp vian id(&vian1->vian Id, &vian2->vian Id);
return (ret);
}

qpsc vc(link1, link2) qlrnk t *link1;
qlink t *link2;
int ret;
Imvct *vc1;
Im~vc~t *vc2;
vc1 = (Im vc t *) link1->data;
vc2 = (Im vc t *) link2->data;
ret = cmp vc addr(vc1, vc2);
} return (ret), qpsc pv(link1, link2) qlink t *link1;
qlink t *link2;
int ret;
Im port vian t *pv1;
Im port~vian~t *pv2;
pv1 = (Im port vian t *) link1->data;
pv2 = Qm port vian t *) link2->data;
ret = cmp pv addr(pvl, pv2);
return (ret);
}

qpsc mv(linkl, link2) qlrnk t *link1;
qlini< t *link2;
int ret;
Im mac vian t *mvl;
Im~mac~vian~t *mv2;

WO 94/07316 2 1 ~1 ~ 1 S d~ PCI/US93/08674 .~/s . .
Im_util.c mv1 = (Im mac_vlan t *) link1->data;
mv2 = (Im~mac viarl~t *) link2->data;
ret = cmp mv addr(mv1, mv2);
return (ret), #ifdef UNIX
MHW GetNodeNumberO
retum (42);
}
MHW GetShelfNumberO
return (O);

#else /* ifndef CERNEL */
MHW GetNodeNumberO
tSHARED RW *shr;
shr = (tSHARED RW *) GetSharedPO;
retum (shr->Node);

MHW GetShelfNumberO
return (O);

#endif /* Ifdef CERNEL */

W O 94/07316 PC~r/US93/08674 .

2 1 4 ~
q.c /* q.c * COPYRIGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
*/
* Des~lipLion:
<Desc,i~JLion of the general category of file conL~r,t~>
* Routines:
* <An OPTIONAL list su,-,l.,arki~,g the routines in this file>
AAAAAAAAAAAAAA--AAAAAAAAAAAAAAAA~NL~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAlAAAAAAAAA/
#include "q.h"
init qlink(link, p) qlink t *link;
int ~ *p;
{ l;nk >prev = NULL;
link->next = NULL;
Iink->q = NULL;
link->data = p;

init q(q) queue t *q;
q->head = NULL;
q->tail = NULL;
q->count = o;

putq(link, q) queue t *q;
qlink t *link;
link->q = q;
link->prev= q->tail;
link->next = NUil;
if (q->tail == NULL) {
q->head = link;
} else {
q->tail->next = link;
q->tail = I~nk;
q->count+ +;
}
putq before(link, before) q ink t *link;

WO94/07316 ~ 4~ PCr/US93/08674 -q.c qlink t *before;
queue t *q;
q = before-~q;
link->q = q;
link-~prev= before->prev;
link->next = before;
before->prev = link;
H (IS HEAD LlNK(iink)) {
q- > head = link;
} else {
link-> prev-> next = link;
q->count+ +;

putq after(link, after) qrnk t *link;
qlink~t *after;
queue t *q;
q = after->q;
link->q = q;
U (q == NUiL) {
link->prev = after;
link->next = after->next;
after->next = link;
if (IS_TAIL_LlNK(link)) {
q->tail - link;
} else {
link->next->prev = link;
q-> count+ +;
}

putq head(link, q) qrnk t *link;
queue t *q;
link->q = q;
link->next = q->head;
link->prev= NULL;
if (q->head == NUi L) q->tail = I~nk;
} else {
q-> head-> prev = link;

W O 94/07316 PC~r/US93/08674 .

7 ~ q.c q->head = link;
q->count+ +;

putq tail(iink, q) qrnk t *link;
queue t *q;
putq(link, q);

rmq(link) qlink t *link;
queue t *q;
q = link->q;
if (link->next == NULL) {
q->tail = link->prev;
} else {
Iink->next->prev = link->prev;
}

if (link->prev == NULL) {
q->head = link->next;
} else {
link->prev->next = link->next;
}

link->prev= NULL;
link->next= NULL;
link->q = NULL;
q->count-;

Int *
traverse q(q, func, ar~) queue t *q;
int ~ *(*func) O;
int *ar~;
{
qlink t *llnk;
qlink t *next;
int *ret;
ret = NULL;
for (link = q->head; link k NULL; link = next) {
next = link->next;
ret = (*func) (link->data, arg);
if (ret != NULL) {
break;

WO 94/07316 ~ PCI~/US93/08674 q.c }

return (ret);
}
putq sorteci(iink, q, func) q Ink t *link;
queue t *q;
int (*func) O;
{
qlink t *cur;
qlink t *next;
int ret;
ret= 1;
for (cur = q->head; cur l= NUil; cur = next) {
next= cur-~next;
ret = (*func) (link, cur);
if (ret <= O) {
putq before(link, cur);
break;
}

if (ret > O) ~
putq tail(link, q);

W O 94/07316 PC~r/US93/08674 .

2 1 ~ '1 q.h * COPYRiGHT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNL~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
#ifndef Q H
#define Q H
#ifndef NULL
#define NULL (0) #endif /* INULL */
struct qlink s {
struct qlrnk s *prev;
struct qlink~s *next;
struct queue s *q;
Int *data;
};
typedef struct qlink s qlink t;
#define SIZE QLINK (sizeof(qlink t)) struct queue s {
qlink t *head;
qlink t *tail;
int count;
};
typedef struct queue s queue t;
#define SIZE QUEUE (sizeofrqueue t)) #define QUEUE LEN(q) ((q)->count) #define IS_EMP~Y Q(q) ((q)->head =- NULL && (q)->tail == NULi ) #define HEAD Q(q~ ((q)->head) #defineTAlL Q(q) ((q)->tall) #define IS HEAD LlNK(link) ((link)->prev == NULL) #define IS TAIL aNK(link) ((link)->next == NULL) extem Int *traverse q0;
extem int put sortedO;
extem int init qlink0;
extern int init~q0;
extern int putq0;
extem int rrnqO;
extem int put beforeO;
extern int put afterO;
extern int put headO;
extern int put~ta~l0;
#endif /* IQ H */

WO 94/07316 2 1 4 ~ PCr/US93/08674 ~2~
SVC.C

/* SVC.C
*

* COPYRIGHT 1992 ADAPTIVE CORPOPATION
* ALL RlGi-iTS RESERYED
*/

statie ehar seesid[] = ~96A96~;
#ff Idefined(CERNEL) && defined(RT68i~
#define ERRLOG printdbg #define prinff prT,I~ iiJçi #endif #include "atm.h~
#inelude ~svc.h~
#inelude "unipciu.h~
#include ~'debug.hU
#ineludeLsve uti.h"
#ineludeUif atm.h"
/* debugging and tracing stuff */
#define TL1 #defineTL2 svc trace>1 #define TL3 sve trace>2 #define TL4 sve trace>3 iÇ~define TL5 svc traee>4 int sve traee = 2;
/*
* switeh virtual coul1ec~iol1 serviee * This module provides basic virtual conneetion, or ve, ~"anage",e,lt * services to users of the atm layer services. a service l~le,~dce * to the SVC signaling protocol is provied via the sdu inputO
* routine. In addition the virtuai eo"-,e.:tion data strueture, vcte, * provides hooks for upper layer p.oloculs so that they need not * l~i-'- ful~lo~ ly the signaiing module requires itsself.
* Eaeh upper layer protoeol must reglster routines to be ealled when * payioad frames arrive and siy,-~i:ng service n~ ons arrive.
* ulp registerO is used to register upper layer plu~uools. Aiter a * protocol n:y;~.t~.x itsself it may interaet with the s~gnaiing * module by sending/r~ee.~/i.,g siy"aiiug serviee data units (whieh * have the same strueture as the signaiing PDUs, found In unipdu.h).
* The service data in~t:lldce is desc,;i e in [l. The eail t,ler~nee * field in the setup request SDU Is ignored. The eail r~re.~nce In * all other SDUs is a pointer to the virtuai eonneetion data * strueture. Plutoc-ols may use this pointer to eail sve IneO and * sve deeO to add r~r~, enees. Protoeols may call W O 94/07316 PC~r/US93/08674 .

svc.c * svc find next peerO to find all the vcte's ~s specific states.
* Typically this rs used to find an existing cu"nel;tion to a peer * for re-use.
*
* Pointers, Conventions & Data Structures * vp points to a virtuai colllle~tiùll table entrye, vcte. There Is * one vcte per virtuai connectiol). Each vp is on two hash chains, * one linked by call ~e~rt"lce and one linked by peer address. pc * polnts to the physlcal 1, It~l ~dce with which a pciu or vc is * A~oGI ~ 3d Each physical l"lel~ace has a pcif structure which * describes the cllar~,cteri:,lics of the interface and has the virtual * conllection hash tables, pc vcalltab[l & pc vpeertab[] and incoming * vpci lookup table, pc ~vpci tab[]. pdu (points to) a * plulucol data unit xdu (poTnts to) a protocol or se~vice * data unit StiU (points to) a service data unit pdu, sdu, &
* xdu all point to a buffer which can be extended at least as far as * the largest supported UNI l,dns" ~ ~ s;~lldiillg data unit. atp * points to an atm lan interface structure. Conceptually atm lans * are layered above the virtual circuit (and aal) layers. The * virtual circuit layer needs a list of list port addr~:~ses per * physical interface. The atmif structures conveneintiy have port * ad i, ~ses are are statically linked off pc~s at boot so this * module uses (and "d,lages) those port addl~sses. ulp points to an * upper layer protocol table entry, ulptab. A ulp uniquely * identifies an upper layer protocol to which sigllali,lg SDUs and * payioad traffic are directed.
* Messages, .~ fiQnl non-reuse policy.
*

* it~es~ges passed to us from below or above must be aligned on 4 byte * boundaries. i~1essages are not re-used. When this module needs * memory for a message it "~ s a newti buffer by calling * atm alloc msgO. This routine must provide an aligned buffer at * least 104 bytes long. ~5~92S received are not re-used because * while they may be large enough to hold a signaling pdu there is * not a convenient way to determine where the physical bufier begins * and ends. Rather than pass physical buffer boundaries around with * the buffers they are simply not reused.
* Multicast Server VCs *
* VCs with the VCTEF MCAST SERVER flag are c~uneo~ s to an ATM LAN
* multicast server. The network directs these requests to servers.
* These VCs do not actually carry payload. The vcte ivpci and * vcte ovpci fields contain network specific control ill~orll~lion for * these VCs. The server supplies these fields via setup request * and response SDUs.
*/

W O 94/07316 ~ 4 PC~r/US93/08674 SVC.C

#include ~niu.hU /* how many i"tt, rdces */
/*
* Due to the one of brain da",aged OSes this cotie must execute upon * all globR~ variables which are r"~i;fieci at run time must be * R~cessed via a pointer held by that OS.
*/
int ulptab ske= NUUS;
int ivpci tab size = IVPCI TAB SIZE;
int vctab ske = VCTAB SIZE;
int svc ~efault qos = LMil QOS PRIO LO;
int svc ms per tick = 400;
svc init pcH(unit, in peak rate, out peak rate, max vci, max mtu) struct pcif *pc;
struct vcte *vp;
pc = &svc glob->svc pcif[unit];
atm bzero~pc, sizeof *pc);
pc->pc num = unit;
pc->pc num ians = atm nnius[unit~ <= NATMS ? atm nnius[unit]: NATMS;
pc->pc hw max mtu = max mtu;
pc->pc hw max vci = max vci;
pc->pc opeak rate = out peak rate;
pc->pc ipeak rate= in_peak rate;
pc->pc sig = ivc create(pc, i MI GLOBAL CREF TYPE, LMI GLOBAL CREF VALUE
~MI VPCI, L~il VPCI, &atm glob->atm nu~l &atm glob->atm nuli, svc glob->sig ulp, 0, PAYLOAD AAL 4);
if (svc pcm) {
svc new state(pc->pc sig, VCS WGRC);
} else {
svc new state(pc->pc sig, VCS ACTIVE);
} pc->pc_sig->vcte ticks = o;
H (pc->pc num lans) atm attach(pc~; /* if atm lans are configureci attach * them */
else atm initO; /* neeciecd even if no atm lans * configureti */
sw schec timeout(pc);

/*
* Once every tick (co,~ "e ~ by svc ms per tlck) all the VCs are r W O 94/07316 PC~r/US93/08674 2 1 4 ~ 1 5 1 sv-c.c ,~
* seanned looking for timeout eond;lions. Both the slylldliu9 VC and * payload VCs are serv~ced from here. When vcte ticks Is * decremented to O either an IDU TO or and IDU MiAX Rt I ItltS message * Is sent to the VC state machlne.
*/
int svc max retranslVCS LAST + 1] = {O, O, O, 7, 7, O, 7, -1, -1, -1, 7};
int sve new tickslVCS LAST + 1] = {O, O, O, 2, 2, O, 2, 4, 4, 4, 1};
int svc backoff[l = {1, 2, 4, 8, 16, 24, 24, 24, 24};
Int sve max retires = sizeof(sve backoff) / ~ eur(int);
Int sve timed states = (1 <~ VCS WC) ~ VCS WCACK~ VCS WRC) VCS W~C) 1 ~ VCS WAR) I ~ ~ ~ VCS ACTIVE~;
Int sve backoff states = ~ VCS WC) I (1 ~ VCS WCACK) I (1 ~ ~ VCS WRC);
svc timeout(pc) { struct pcif *pe;
struct vcte ~vp, *next;
struct release comp *to;
int i;~
int s;
if (pc->pc sig->vcte state == VCS INACTIVE) {
svc sched timeou~pc);
return;
for (i = O; i < VCALLTAB SIZE; i+ +) {
s = splimpO;
next = pc->pc vealltab[i];
while (vp = next) {
ASSERT(VALID VP(next));
next = vp->vcte next cref;
if (vp->vcte cref~type~l vp->vcte cref value) /* not global eref */
ASSERT(VALiD STATE(vp->vete state));
U (vp->vete tieks -= O) /* no tirneouts scheduleci */
continue;~
ASSERT(~ALiD STATE(vp->vcte state));
ASSERT((1 ~ ~ vp->vcte state) ~ sve timeci states);
vp->vcte tieks-;
if (vp->vete tieks <= O) { /* timer has expired */
if ((to = (~truct release comp *) atm alloc msgO) == ) {
* no memory, schedule a * timeout, and quit */
vp->vcte ticks+ +; /* back off ticks for * this ve */
svc scheci timeout(pc);
return;

W O 94J07316 2 1 4 ~ 1 5 ~ PC~r/US93/08674 .
SVC.c }

/*
* send IDU TO H retrans leit else * send IDU_MiAX Ri--TRlES
if (vp-~vcte timeouts < svc max retrans~vp->vcte state~) {
to->lmi cref type = vp->vcte cref type;
to->lmi~cref~vaiue - vp->vcte cre~ value;
to->lmi pdu type= IDU TO;
vp->vcfi ticks = svc bacl~ufi[vp->vcte timeouts++] *
svc new ticks[vp->vcte state];
} else ~
to->lmi pdu type = IDU MAX ~tl~ltS;
svc xdu(vp-~vcte pcif, vp, to, sizeof(*to));

splx(s);
svc_sched timeout(pc);

* The sig- - ,g software is a~cessec via svc pdu0 and svc sdu0.
* Users call svc sdu0 with a sdu and the aaTlayer calls svc pdu0 * with a pdu. The caller is resposnlble for pass mess~ges In * contiguous memoN, properiy aligned. The caller is responsible for * providing syncl,loni lion, i.e., ~ kk- g some global se,--aphore, * turning off interrupts, etc. This routine hor~eshoes down but not * up. That is a SeN~ce request will not trigger calls to an upper * layer sdu routine.
.t * Before calling svc xdu0 the vc table is sea-ched for call reference * in the pdu. If none is found and the call refemece type is PVC
* and the pdu type is a release then the cail r~ nce is assumed * to be an incoming vc~. These are gene- lled when the network * receives payioad cells on a release VC.

svc pdu(pc, pdu, length) struct pcif *pc;
struct release *pdu;
int length;
int bad pdu;
struct vcte *vp;

if (pdu->lmi proto l= LMI PROTOCOL 1 1 Isvc valid pdu type(pdu->lmi pdu type)) {
"

W O 94/07316 PC~r/US93/08674 2 ~ 4 ~
SVC.C

atm free msg(pdu);
retum PROTOCOL ERR; /* invalid protocol or pdu * type */ ~
/*
* when sig vc ~s not active only accept pdus w/ gloW call *jt:ie,t:nce H (pc->pc sig->vcte state l= VCS ACTIVE &&
I(pdu->lmi cref type == LMI GLOBAL CREF TYPE &&
pdu->lmrcref value == U~ GLOBAL CREF VALUE)) {
TR0(TL3, ~srg vc not active, pdu dropped~n~);
atm free msg(pdu);
return NETWORK UNAVAIL;
if (pdu->lmi pdu type <= LMI PDU LAST) svc glob->svcst~tpcll~ sent~pdu->lmi pdu type]++;
/* if pdu doesnt parse ok, change pdu type to invalid */
if (bad pdu = svc parse xdu(pc, pdu, length)) {
svc glob->svcstat.parse causes[bad pdu]++;
pdu->lmi_pdu type = IDU INVAUD PDU
LMI SET EUEMENT(&pdu->lmi cause, LMI RELEASE CAUSE, bad pdu);
length = sizeof(*pdu);
vp = svc find cref(pc, pdu->lmi cref type, pdu->lmi cref vaiue);
* if call ref lookup fails and release pdu treat call ref as * a PVC vci if (!vp && pdu->lmi pdu type == LMI PDU RELEASE &&
pdu->lmi cref type == Uvil CREFTYPE PVC) vp = ivpci-to vcte(pc, pdu->~mi cref vaiue);
return svc xdu(pc, vp, pdu, length);

/*
* svc sciu0 does preliminary service data unit parsing anci calls * svc xdu0 for the real work.

svc sdu(pc, vp, pdu, length) struct pcif *pc;
struct vcte *vp;
struct xdu *pdu;
int *length;
{ int bad pciu;
/* if the signaling VC is not active reJect service requests */
if (pc-~pc sig->vcte state ~= VCS ACTIVE) {

WO 94/07316 ~1 4 ~1 5 ~ PCI~/US93/08674 . . .
22~Y
SVC.C
-18g atm free msg(pciu);
return Ni~rWORK UNAVAiL;
}

ASSERT((pdu->lmi cref type & i~l CREi~YPE MASlq == LMI CREi~YPE SVC);
* reJect service requests with unknown encoding or invaiid * request types */

if (pdu->lmi proto l= Livil PROTOCOL 1 1 Isvc vaiid sdu type(pdu->lmi pdu type)) {
atm ~ree msg(pdu);
return UNKNOWN MSG;
} else if (bad pdu =~svc parse xdu(pc, pdu, length)) {
svc glob->svcst~t;~rse causes[bad pdu]++;
atm free msg(pdu);
retum bad pdu;
return svc xdu(pc, vp, pdu, length);
}

/*
* svc xduO service data units and protocol data units come here.
* If they failed their respective parsing they have been turned into * IDU INVALiDs which, in most cases result in release PDUs being * sent, via svc reJect pduO. Next the state specific routine for vp * is called. If vp is zero the routine for VCS CLOSED, * svc closedO, is called.
Int svc closedO, svc wsrO, svc wcO, svc wcackO, svc estabO, svc wrcO, svc~inactiveO, svc activeO, svc wgrcO, svc warO, panicO;
int (*(svc state functions[])) O = r panic, svc closed, svc wsr, svc wc, svc wcack, svc estab, svc wrc, svc inactive, svc wgrc, svc war, svc active };
char *svc state names[] = {~u~deri~ed~'closed~Uwsr'~wc~uwcack, ''estabU~ Uwrc~, uinactive~, "wgrc~, ~war~, ~active~};
Int svc nnames = skeof(svc state names) / sizeof(char *);
svc xdu(pc, vp, pdu, len) struct pcif *pc; /* physical unit */
struct vcte *vp;
struct xdu *pdu;
Int len;
{

int state, rtn, trace ievel;
ASSERT(VALiD PC(pc));
ASSERT(PDU Al~GNED(pdu));
-W O 94/07316 PC~r/US93/08674 ~14~1~4 ~
svc.c ASSERT(len >= sizeof(structImi hdr));
H (vp) {
state = vp->vcte state;
H (vp->vcte cref type I vp-~vcte cref value) /* if not globarcail ~ ,t,nce *~
ASSERT(VALiD STATE(state));
} else state = VCS CLOSED;
if (pdu->lmi cref type I pdu->lmi cref value) trace level = T-L2;
else trace level = TL3;
TR4(trace ievel, 'Xdu vp=%x %s %s %d\n~, vp, svc state names[state]
svc-xdu type str(pdu->lmi pdu type), len);
if ((pdu->lmi cref type I pdu->lmi cref value) && TL2) svc trace pdu(pdu, len, 1, LMil VPCI), if (pdu->lmi pdu type == IDU INVAi iD PDU) rtn = svc~reject pdu(pc, pdu, len, vp), else rtn = (*svc state functions[state]) (pc, pdu, len, vp);
TR3(trace ievel, '~due vp=%x %s %d\n~, vp, vp ? svc state names[vp->vcte state]: ~was closed", rtn);
return rtn;
}

/*
* Clear any previous timers and set new ones. Aiso log transitions * to new states.
*/
svc new state(vp, state) struct vcte *vp;
K (vp->vcte_state l= state) svc log new state(vp, state);
vp->vcte timeouts = 0;
K ((1 < < state) & svc timed states) vp->vcte ticks = svc new ticks[state];
else vp->vcte ticks = 0;
vp->vcte state = state;

WO 94/07316 ~ i 4 PCI'/US93/08674 -SVC.C
191 .
/*
* State function for signaling vc tn inactive state should never be * called.
svc inactive(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
atm free msg(pdu);

* State function for signaling vc in waiting for global release * state. The signaling VC stays in WGRC until we geta a global * release comp. config status enq/resps are ignored. Other status * enquires and lesponses are processed normally. There Ts no limit * to how long we stay ~n this state (svc new stateO resets the * number of timeouts to zero.) */
svc wgrc(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
switch (pdu->lmi pdu type) t case LMI PDU STATiJS RESP-case LMI PDU STATUS ENQ:
if (pdu->lmi status type != LMI STATUS CONFIG) svc status(pc, pdu, len, vp);
case ID~ TO:
case IDU MAX RETRIES: /* fallen Into */
svc new state(vp, VCS WGRC); /* to reset timer &
* timeout count */
svc send release(vp);
break;
case i MI PDU RELEASE:
svc send rerease comp(vp);
break;
case LMI PDU REi EASE COMP:
svc new state(vp, VCS WAR);
svc_request config(pc);
break;
atm free msg(pdu);
} retum 0;

W O 94/07316 - PC~r/US93/08674 4 ~o svc.c * State function for signaiing vc in waiting for address rt:sponse * state. This state is left when we receive a ~ ;oonse to one of * our config requests. svc reconflgO actually challges the state to * active. releases and release comps do not effect us bec~ se we * have come through the WGR-C state insuring that all VCs have been * cleared and we reJect any ~ "".,1~ to setup new VCs in this state.
*/
svc war(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
switch (pdu->lmi pdu type) case IDU TO: ~ ~
case IDU MAX Rt I ~ItS:
svc new state(vp, VCS WAR); /* to reset timer &
~* timeout count */
svc request config(pc);
break;
case LMI PDU STATUS ENQ:
if (pdu->lmi status type == Li~AI STATUS CONFIG) svc send configTpc);
else svc status(pc, pdu, len, vp);
break;
case LMI PDU STATUS RESP:
if (pdu->lmi status type == LMI STATUS CONFIG) svc reconfig(pc, pdu, len, vp); /* sets state to ACTIVE */
else svc status(pc, pdu, len, vp);
break, caseLi\ll PDU RELEASE:
svc send rerease comp(vp);
break;
case LiVII PDU RELEASE COMP:
break;
}
atm free msg(pdu);
retum 0;
}

/*
* state function for signaiing vc is active, we just send keep * alives and hope not to get releases, after max retries we release * all vcs, send a global release & go to waiting for global release * complete.

WO 94/07316 2 1 ~ 4 ~ Pcr/us93/o8674 .

O?a~
svc.c ,9~
*/
svc active(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pdu;
Int len;
struct vcte *vp;
struct atmK *atp;
switch (pdu->lmi pdu type) {
case IDU TO:
svc request config(pc);
break;
case LMI PDU STATUS ENQ:
H (pdu->lmi status type = = LMI STATUS CONFIG) svc send configTpc);
else svc status(pc, pdu, len, vp);
break, - case LMI PDU STATUS RESP:
K (pdu >lmT status type != LMI STATUS CONFIG) {
svc status(pc, pdu, len, vp);
break;
} else if ~svc check config(pc, pdu, len)) {
vp->vcte cause - 0;
svc new state(vp, VCS ACTIVE); /* config same, reset * timeouts */
break;
} else vp->vcte cause = NUMBER CHANGED;
/*
* If we get here we must delete all atm lans, * release all VCs and vcte cause is set so it gets * logged corectly. We sned a release comp K a * release triggered this.
*/
caselDU MAX RtlnltS:
case LMI PDU RELEASE: /* fallen Into */
svc release all(vp);
svc~send re~ease(vp);
K (pdu->lml pdu type == LMI PDU RELEASE) {
svc set cause~vp);
svc send release comp(vp);
} else if (pdu->lmi pdu type == IDU MAX P~tlnltS) vp->vcte cause = NETWORK TIMEOUT, svc new state(vp, VCS WGRC);
for~atp - pc->pc atm~; atp; atp = atp->ati next) atm delete lan(atp);
break;

W O 94/07316 PC~r/US93/08674 2 ~ 3 SVC.C
}

free and out:
atm free msg(pdu);
return O;

* svc check configO returns true N this conflg resp is the same as * theTast.
*/
svc check config(pc, pdu, len) struct pclf *pc;
struct config *pdu;
int len;
int rtn;
H (!pc-> pc last config) {
pc->pc rast config = (u char *) atm alloc msgO;
if (Ipc->pc iast config) r - prinff("svc check config: no memory\nU);
return O;
pc->pc iast config ien = O;
/*
* dumb, simple, but almost foolproof check for configuration * challges.
rtn = (pc->pc last config len == len &&
(atm bcmp(pc->pc rast config, pdu, len) == O));
return rtn;
}

/*
* 2. set maximums based on i~il CONFIG element 3a. H port element * then add one lan per element. 3a. else configure for back-to-back * Op~l dliOI~. , */
svc t:cor,rig(pc, pdu, len, vp) struct pcif *pc struct status enci *pdu;
Int fin;
struct vcte *vp;
struct config elem *ce;
struct port addr elem *pae;
struct atmif *atp;

WO 94/07316 ~ PcI/US93/08674 , .
SVC.C
-19~

ASSERT'pdu-~lmi pdu type == LMI PDU STATUS RESP);
ASSERT pdu->lmi status type == LMI STATUS C~NFIG);
ASSERT SVC PARSED(LMI CONFIG ENQ));
ASSERT~SVC PARSED(LMI CONFIG RESP));
ce = (struct config elem *) SVC GET(LMI CONFIG RESP);
pc->pc net max vci = ce->af max vci;
pc->pc net max vcs = ce->a~max vcs;
pc->pc net max qos = ce->af max qos;
H (!pc->pc rast config) {
pc->pc rast config = (u char *) atm alloc msgO;
if (Ipc->pc rast conf'g) r prlnff(Usvc rt cotlri~; no memoty\nU);
return;
}

atm bcopy(pdu, pc->pc last config, len);
pc->pc last config len - len, svc_new_state(vp, ~CS ACTIVE);
if (!SVC PARSED(LM! FORT ADDR)) {
H (ce->af my address.aa type != MT MAC) {
pc->pc flags = 0;
return;
}

/* configure back-to-back niu s */
pc->pc flags l= PC!F NIU TO NIU;
H (ATM ADDR GT(ce->af my address, pc->pc atmif->ati mac)) pc->pc flags I = PCIF ~T*ER MAC ADDR IS HIGHER;
for (atp = pc->pc atmH; atp; atp - atp->ati next~
atm niu to_niu~tp);
return;
}

/* configure one atm lan per port addr element */
pc->pc flags &= ~(PCIF NIU TO- NIU I PCIF OTHER MAC ADDR IS HIGHER);
pae = ~struct port addr e~em q SVC GET(LMI PORT ADDR), atp = pc->pc atmH;
while (((caddr t) pae < (caddr t) pdu + len) && atp) {
ASSERT(pae->af type = = LMI PORT ADDR);
atm add lan(atp, pae->af port, pae->af mid, pae->af mcasts, pae->af mtu);
pae+ +;
atp = atp->ati next;
}

/
* send our configuration in respond to the parsed config enq. Our -W O 94/07316 PC~r/US93/08674 4 ~
SVC.C
.96 * config elem is based upon compiled table sizes and the h/w vci * lookup table.
svc send config(pc) { struct pcif *pc;
int len;
struct config elem *ce;
struct status enq *pdu;
if (I(pdu = (struct status_enq *) svc alloc pdu(Li~ll PDU STATUS RESP, pc->pc sig))) return 0;
pdu->lmi status type = LMI STATUS CONFIG;
ASSERT(~VC PA-RSED(LMI-CONFIG ENQ));
ce = (struct config elem *) & pdu[1], /* copy requestors config Info to resp */
*ce+ + = *(struct config elem *) SVC GET(LMI CONFIG ENQ);
/* then add our config elem */
ce->af type= LMI C~NFIG RESP;
svc add config(pc, ce);
len - sizeof(*pdu) + skeof(*ce) * 2;
aal send msg(pc->pc sig, 0, pdu, len);

* send request for configuration, include our config elem svc request config(pc) struct pci~ *pc;
struct config_elem *ce;
struct status enq *pdu;
ASSERT(VALID PC(pc));
if (I(pdu = (struct status enq *) svc alloc pdu(i MI PDU STATUS ENQ, pc->pc sig))) return 0;
pdu->lmi status type = LMI STATUS CONFIG;
ce = (struct con~ig elem *) & pdu[1];
ce-> af type = i- Ml CONFIG ENQ;
svc add config(pc, ce);
aal sen~msg(pc->pc slg, 0, pdu, skeof(*pdu) + skeof(*ce));

svc add config(pc, ce) struct pcif *pc;
struct confi~_elem *ce;
ce->af version = LMI VERSION;
ce->af max vci = pc->pc hw max vcl;

WO 94/07316 2 1 ~ ~ 1 5 4 Pcr/US93/08674 -~3 SVC.C
1 g7-ce->af max vcs = VCTAi3 SIZE;
ce->af~max~qos = 0;
ce-~af my address = pc->pc atmif-~ati mac;
., * state function for payioad vc, vc ~s closed. we ailocate a vcte * structure. all pdus other than setup are ignored. This should * probably send releases. and hope not to get releases, after max * retries we release all vcs, send a global release & go to waitinçi * for globai release complete.
*/
svc closeci(pc, pciu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
{

Int error= o;
swHch (pdu->lmi pdu type) {
case SDU SETUF RE~:
ASSERl~(lvp);
vp = svc alloc vcte(pc, pdu);
if (!vp) {
error = NO RESOURCES;
break;
if (error = svc setup req unsalv~ge~hl~(pciul vp)) {
svc close(vp);
break;
}

svc upciate user info(vp);
svc~new state(vp, VCS_WC);
svc send setup(vp);
break;
case SDU REU--ASE REQ:
case SDU SETUP RESP:
atm free msg(pdu);
return INVAUD STATE;
break;
case UVil PDU SETUP:
ASSERT(lvp), vp = svc ailoc vcte(pc, pcu); /* we need to alloc a vp * to sent a release ! */
if (~vp) break; /* try to get mem when setup ..

WO 94/07316 PCr/US93/08674 2 ~
SVC.C

* ~trdllslllitted */
if (svc setup unsalvege~h'Q(pdu, vp)) {
svc send retease(vp);
svc~close~vp);
} else {
svc upciate user info(vp)-svc new state(vp, VCS WSR);
svc send setup ind(vp~
}
break case LMI PDU STATUS ENQ:
case LMI PDU CONNECT:
case LMI PDU CONNECT ACK: /* turn mi~g~ pdu Into a * release and send it */
svc send release pdu(pc, pdu, len);
return 0 case LMI PDU RELEASE: /* our release comp may have been * dropped */
pciu->lmi cref_type^= LMI CREFDIRECTION MASK;
pdu->lmrpdu type = LMI PDU RELEASE COMP;
- aal send msgTpc->pc sig, 0, pd-u, sizeof(struct release comp));
retum 0;
case LMI PDU RELEASE COMP:
case LMI PDU STATUS hRESP:
break;
atm_free_msg(pdu);
return error;
}

/*
* state function for payioad vc, vc is waiting for a setup resp from * user.
*/
svc wsr(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct.vcte *vp;
{
switch (pciu-> Imi pdu type) f case SDU SETUF RE~:
atm free msg(pdu);
return INVALiD STATE;
case SDU SETUP RESP:
ASSERT(\/ALID ~IP(vp));
svc setup resp vcis(pdu, vp);

W O 94/07316 ~ 5 4 PC~r/US93/08674 ~7 SVC.C
,99.
svc upciate user info(vp);
svc new state(vp, VCS WCACK);
svc~send com)ect(~/p);~
break;
case SDU RELEASE REQ:
svc update user info(vp);
svc~set cause(vpl;
svc new state(vp, VCS WRC);
svc send release(vp);
break;
case LMI PDU SETUP:
case LMI PDU CONNECT:
case LMI PDU CONNECT ACK:
break; /* protocol voilation, ignore */
case LMI PDU RELEASE:
svc_update user info(vp);
svc set cause(vp~;
svc send release comp(vp);
case LMI PDU RELEASE COMP:/* fallen into */
svc send rerease ind(vp);
svc close~vp);
break;
case LMI PDU STATUS ENQ:
case LMI PDU STATUS RESP:
svc status(pc, pdu, len, vp);
break;
}

atm free msg(pdu);
return O;
}

* state function for payload vc, vc is waiting for a connect from * peer */
svc wc(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
switch (pdu->lmi pdu type) {
case LMI PDU CONNECT:
* if nego;~tion succeeds goto estab ~I,an~,:..c start * releasing */
if ((vp->vcte cause = svc connect unsalv~g~ e(pdu, vp)) == O) svc new state(vp, VCS ESTAB);

WO 94/07316 PCl'/US93/08674 2 ~ 4 ~?38 SVC.C

svc send cack(vp);
svc update user Info(vp);
svc send setup conf(vp);
else {
svc new state(vp, VCS WRC);
svc send release(vp);
svc~send~release ind(vp);
}

break;
case IDU TO:
svc send setup(vp);
break;
case IDU MAX Ht I HltS: /* give up and start releasing */
vp->vcte cause= NO ANSWER FROM USER;
svc new state(vp, VCS WRC);
svc send release(vp); ~
svc send release Ind(vp);
break;
case SDU SETUP REQ:
case SDU SETUP RESP:
atm free msg(pdu);
return IN~ALID STATE;
case SDU RELEA-SE REQ: t* user releases, start ,~lea.;,.g */
svc up~ate user info(vp);
svc~set cause(vp~;
svc~new state(vp, VCS WRC);
svc send release(vp);
break;
case LMI PDU RELEASE:
svc update user Info(vp);
svc set cause(vp~;
svc send release comp(vp);
case LMI PDU RELEASE COMP: /* fallen into */
svc send rerease ind(vp);
svc close~vp);
break;
case LMI PDU SETUP:
case LMI PDU CONNECT ACK:
break;
case i MI PDU STATUS ENQ:
case LMI PDU STATUS RESP:
svc status(pc, pdu, len, vp);
break;
}

atm free msg(pdu);
return 0;
}

WO 94/07316 2 1 4 4 1 ~ 4 PC~/US93/08674 .?35 SvC.C

* connect ne~o; -~;OIl, we blindly accept whatever peer incoming vci * he wants; we try to ~r-co~ the peers outgoing vci, reassignlng * K necessaly. The setup conf will inform user of finai vci's. We * lower out outbound peak to the the peers inbound peak rate. We ~ told the peer our inbound rna~ If he Is golng to send fast we * reJect with service unavallable.
*/
svc connect unsaiv ~ ' 'a(~iu, vp) struct vcte *vp;
struct connect *pdu;
vpci t vc~;
u long rate;
if (SVC PARSED(LMI IQOS PEAK BW)) { /* reset outbound peak */
rate - SVC Gi-T(LMI IQC~S PEAK BW);
if (rate < vp->vcte opeak rate) vp->vcte opeak~rate = rate;
_ if (SVC PARSED(LMI_OQOS PEAK BV\I) &&
svc parmsrLMI OQOS Pi--AK BVV~.par value > vp->vcte pcif->pc ipeak rate) return QOS UNAVAILABLE; /* peer insists on sending * fast than we can recv */
H (vp->vcte flags & VCTEF MCAST SERVER) {
ASSERT(vp->vcte ivpci 1- 0);
ASSERT(vp->vcte ovpci != 0);
return 0; /* vci's are ignored on the multicast * server */
}

ASSERT(SVC PARSED(LMI IVPCI));
if ((vci = SVC Gi-T(LMI IVPCI)) != vp->vcte ovpci) vp->vcte ovpci = vci, ASSERT(SV-C PARSED(LMI_OVPCI));
if ((vci = SVC GET(i MI OVPCI)) I= vp->vcte ivpci) {
/* ~v~pci cliall~td */
if (ivpci to vcte(vp->vcte pcif, vci)) /* ff new one already In use */
retum vp->vcte cause - VCI UNACCEPTABi E;
ASSERT(vp->vcte~pcH->pc ivpci tab[vp->vcte ivpci] == vp);
vp->vcte pcH->pc ivpci tab[vp->vcte ivpci] = 0;
vp->vcte pcH->pc ivpci tab[vci] = vp;
vp->vcte ivpci = vci;
retum 0;

/
* setup ne~ot ~io~, we negoidle peer ovpci's and we blindly accept -WO 94/07316 PCI~/US93/08674 2 ~ 5 ~
~0 SVC.C

* peer ivpcl s bec~se we could care less if they want to screw * II,er.,__lvcs. After cailing this routine both the vcl s will be * assi~"ed. The user isn t ailowed to change vci s.
*/
svc setup unsaivzJf- ~(pdu vp) struct connect *pdu;
struct vcte *vp;
vpc~ t vci;
if (Isvc find parsed ulpO) return vp-~vcte cause = UU UNAVAILABLE;
K (vp-~vcte flags~ VCTEF MCAST SERVER) return 0; /* vci s are igrlored on the multicast * server */
/* set peak rates giving p~re,t:i)ce to request~ci values */
if (SVC PARSED(LMI IQOS PEAK BW)) {
vp->vcte opeak rate = SVC GET(LMI IQOS Pi AK BW);
if (vi~>vcte opeak rate > vp->vcte pc-if->pc opea~ rate) vp-~vcte~opeak rate = vp-~vcte pcif-~pc opeai~ rate;
} else vp-~vcte opeak rate = vp-~vcte pcif->pc opeak rate;
if (SVC PAi~SED(L~il OVPCI)) { /* check that ivpcl~s * available */
if (ivpci_to vcte(vp->vcte pcif SVC GET(LMI OVPCI))) {
/* request ivpci is in use pick another */
if ((vci = svc get ivpci(vp->vcte pcifl) == o) return vp->vcte cause = NO VCI AVAIL;
} else vci = SVC GET(Livil OVPCI);
} else if ((vci -=svc get rvpci(vp-~vcte pcifl) == o) return vp-~vcte cause = NO VCI AVAIL;
vp-~vcte ivpcT = vci;
vp-~vcte pcif-~pc ivpci tab[vci] = vp;
/* use requesteci ovpci r none regllesteci use ivpci */
if (SVC PARSED(LMI IVPCI)) vp->vcte ovpci = SVC GET(i MI iVPCI);
else vp->vcte ovpci = vp-~vcte ivpci;
return O;
}

/*
* similar to setup pciu necgo~ ~ion only the users notion of incoming * is the same as ours.
/
svc setup req unsalva~e~'e(ixiu vp~

21~1 5ll WO 94/07316 PCr/US93/08674 --SVC.C

struct connect *pciu;
struct vcte *vp;
vpc~ t vci;
struct ulptab *ulp;
H ((ulp = vp->vcte ulp) == 0) retum vp-~vcte cause = UU UNAVAli ABi E;
H (vp->vcte flags~ VCTEF NiCAST SERVER) { /* use server provided * vaiues */
H (SVC PARSED(lNil IVPCI)) vp->vcte_ivpci = SVC GET(iNil IVPCI);
H(SVC PARSED(iJrl OVPCI)) vp->vcte ovpci = SVC GET(iNil OVPCI);
return 0; ~* do not update pc ivpci tab[] */
/* set peak rates giving pit!~r~nce to requestecl values */
vp->vcte opeak rate = SVC PARSED(iNil OQOS PEAK BW) ?
SVC GET(iMi-OQOS PEA-K BW): vp->vcte pcif->pc opeak rate;
H (SVC-PARSED(L~il IV-PCI)) {~/* user thinks he knows a * good ivpci 1*/
H (ivpci to vcte(vp->vcte pcif, SVC GET(iMI IVPCI))) { /* he was wrong */
ASSERT~vp->vcte pcH->pc ivpci tab[vp->vcte ivpci] == vp);
/* try to allocate a ivpci not already in use */
H ((vci = svc get ivpci(vp->vcte pc~) == 0) return vp->vcte cause = VCI UNACCEPTABi E;
} else vci = SVC GET(iMI IVPCI);
} else H ((vci -~svc get ~vpci(vp->vcte_pcH)) == 0) return vp->vcte cause = VCI UNACCEPTABi~;
vp->vcte ivpci=-vci;
vp->vcte pcif->pc ivpci tab[wil = vp;
* if user did not request an ovpcl then use 0 (which means * non specified yet) */
H (SVC PARSED(i~il OVPCI)) vp->vcte ovpci = SVC GET(iMI OVPCI);
else vp->vct~ ovpcl = o;
retum o;

/*
* setup resp vci r" --~ion for mcast server VCs. vci's for other * VCs are ~ ed when the setup jxiu or setup request sdu is * received.
svc setup resp vcis(pdu, vp) struct connect *pdu;

W O 94/07316 PC~r/US93/08674 .

~14~1 5~ svc.c struct vcte *vp;
K (Vp->VctQ flags & VCTEF MCAST SERVER) { /* use server provlded ~ * values */
H (SVC PARSED(LMI IVPCI)) vp->vcte ivpci = ~VC Gi_T(LMI IVPCI);
H (SVC PARSED(LNil O~PCI)) vp->vcte ovpci = SVC GET(LMI OVPCI);
/* do not update pc ivpcr tab[] */
}

return 0;
}

* state function for payioad vc, vc is waiting for a connect ack * from initiator */
svc wcack(pc, pdu, len, vp) struct pcK *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
{

switch (pdu->lmi_pdu type) ~
case LMI PDU SETUP: /* looks like our connect was dropped */
svc send conl~61L(/p); /* so Ibln~ it */
break;
case LMI PDU CONNECT: /* protocol violation */
break;
case LMI PDU CONNECT ACK: /* notKy user vc is * e~iL~blisl,ed */
svc new state(vp, VCS ESTAB);
svc send setup comp~vp);
break;
case IDU TO: /* .~L~n:"uit connect */
svc send connecl(vp);
break;
case IDU MAX RETRIES: /* give up and start releasing ~/
vp-~vcte cause = NO ANSWER FROM USER;
svc new state(vp, VCS WRC);
svc sen~ release(vp);
svc send release ind(vp);
break;
case SDU SETUP REQ:
case SDU SETUP RESP: /* reject con~llseci user requests */
atm free msg(pdu);
return INVALID STATE;
case SDU RELEASE_REQ:

W O 94/07316 2 ~ PC~r/US93/08674 ?~
SVC.C
-20~ .:
svc update user info(vp);
svc~set cause(vp~;
svc new state(vp, VCS WRC);
svc send release(vp); ~
break;
case LMI PDU RELEASE:
svc update user info(vp);
svc set cause(vp~;
svc send release comp(vp);
case D~il PDU RELEASE COMP:/* fallen Into */
svc send rerease ind(vp);
svc_close~vp);
break;
case LMI PDU STATUS ENQ:
case LMI PDU STATUS RESP:
svc status(pc, pdu, len, vp);
break;
}

atm free msg(pdu);
return O;
}

* state functton for payload vc, vc is established. Just wait * around for release pdu or request. If a setup is received then * release this vc and call closed state function for the pdu.
*/
svc estab(pc, pciu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
/* ignore all pdus except status enq/resp for PVCs */
ff ((vp->vcte cref type & LMI CREFTYPE MAS~ == LMI CREFTYPE PVC &&
(pdu->lmr pdu type = = LMI PDU STATUS ENQ 11 pdu->lmi pdu type == LMI PDU STATUS RESP)){
atm free msg(pdu);
return o;
}
switch (pdu->lmi pdu type) {
case LMI PDU SETUIS: /* closed this VC and start seting up * another */
vp->vcte cause = NORMAL RELEASE;
svc sen~release ind(vp);
svc~close~vp); ~
return svc closed(pc, pdu, len, (struct vcte *) O);
case LMI P~U CONNECT: /*r~lr~n~ ff connect ackforpeer */

W O 94/07316 PC~r/US93/08674 ~ ~ 4 ~ svc~c~

svc send cack(vp);
break-case LMI PDU CONNECT ACK: /* duplicate, ignored */
break;
case IDU TO:
case IDU MAX RETRIES:
panic~svc estab tlmeout~
break;
case SDU SETUP REQ:
case SDU Si-TUPRESP:
atm free msg(pdu);
return IN-VALiD STATE;
case SDU RELEASE REQ:
svc update user info(vp);
svc set cause(vp~;
svc new state(vp, VCS WRC);
svc send release(vp);
break;
case LMI PDU RELEASE:
svc update user info(vp);
svc set cause(vp~;
svc send release comp(vp);
case iMI PDU RELEAsE COMP: /* fallen into */
svc send rerease ind(vp);
svc~close~vp);
break;
case LMI PDU STATUS ENQ:
case LMI PDU STATUS RESP:
svc status(pc, pdu, len, vp);
break;
}

atm free rnsg(ixiu);
return 0;
}

/*
* state function for payioad vc, vc Is waiting for a release * Col" '~e No user requests are valid. After max retries or a * release from our peer we close vc out. Everything else (except * status enq/resps) are ignored.
*/
svc wrc(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pciu;
Int len;
struct vcte *vp;
switch (pdu->lmi pdu type) {
case SDU SETUF REQ:

WO 94/07316 2 1 4 4 1 ~ ~ PCI~/US93/08674 SVC.C
-~7-case SDU SETUP RESP:
atm free msg(pdu);
return INVALID_STATE;
case LMI PDU SETUP:
case LMI PDU CONNECT ACK:
case LMI PDU CONNECT
case SD~ REL~ASE REQ:
break; ~
case IDU TO:
svc send release(vp);
break;
case LMI PDU RELEASE:
svc send rerease comp(vp);
case iDU MAX ktlnltS: /* fallen into */
case LMI PDU RELEASE COMP:
svc close(vp~; ~
break;
case LMI PDU STATUS ENQ:
case LMI PDU STATUS RESP:
svc status(pc, pdu, len, vp);
break;
}

atm free msg(pdu);
retum O;

/*
* svc set causeO is called after a release pdu or release req sdu * is received. vcte cause is up~ t~
*/
svc set cause(vp) struct vcte *vp;
H(SVC PARSED(LMI RELEASE CAUSE)) vp->vcte cause= SVC GET~LMI RELEASE CAUSE);
else vp->vcte cause = NORMAL RELEASE;

/
* this routine updates the user info field of the vcte from the xdu * last parsed. The pdu had better stlll be around as the parse * routines Just set a pointer Into the pdu.
*/
svc update user info(vp) struct vcte *vp;
struct Imi uinfo *ui;

W O 94/07316 PC~r/US93/08674 2 ~ 4 ~
svc.c .208 H (SVC PARSED(i~il USER INFO)) {
ui =~struct Imi uinfo *) S~C GET(LMI USER INFO);
H (vp->vcte user info == O) vp->vcte~user~info = atm alloc msgO;
ASSERT(ui->af len <= i Ml~iAX UINFO);
atm bcopy(ui->af value, vp->vcte user info, ui->af ien);
vp-~vcte user info ien = ui-~af ien;
} else I
H (vp->vcte user info) atm free msg~p->vcte user info);
-t ~ i f O ~
}

/*
* svc alloc vcteO 'lor ~ a VC table entry and fills in * appr.)priate fields based upon elements parsed by svc parse xduO.
* Call references are generated here for setup req's, the time * being.
*/
struct vcte *
svc alloc vcte(pc, pdu) struct p-cif *pc;
struct setup *pdu;
{

struct vcte *vp;
struct atm addr *local, *peer-int ~ i;
struct Imi ulp *lu;
ASSERT(pdu->lmi pdu type == LMI PDU SETUP
pdu->lmi pdu type == SDU SETUP REQ);
ASSERT(VAUD PC~pc)) /* grab free vcte entry */
H (I(vp = svc glob-~vcte free)) {
svc glob->svcstat.msg alloc failures++;
retum vp;
svc glob->svcstat.vctes++;
pc->pc num vcs++;
ASSERT(VAI~D VP(vp));
svc glob->vcte free = vp->vcte next cref;
/* update free Irst head */
atm bzero(vp, skeof(*vp));
vp->vcte pcH= pc;
/* set cali ~ererel~ce and insert in cref hash table */
vp->vcte cref vaiue = pdu->lmi cref value;
vp-ivcte~cref~type = pdu->lmi cref type;
H (pdu->rmi pdu type = = UMI PDU SETUP) {

WO 94/07316 ~ PCr/US93/08674 SVC.C

peer = 8pdu-~lmi caller;
local = &pdu->lmi callee;
} else { /* SDU SETUP REQ */
vp->vcte cref type l= LMI CREFDIRECTION MASK;
if (vp->vcte cref value == 0) vp->vcte cref value = (u long) vp & 0xffflff;
peer= &pdu->lmi callee;
local = &pdu->lml cailer;
i = VCALL HASH(vp->vcte cref vaiue);
vp->vcte next cref = pc->pc vcalltab[i];
pc->pc vcalltab[i] = vp;

* set local and peer addresses and insert in peer addr hash * table */
vp->vcte iocal = *local;
vp->vcte peer = *peer;
i = VPEER HASH(&vp-~vcte peer);
vp->vcte next peer= pc-~pc vpeertab[ll;
pc->pc vpeertab[i] = vp;
/*
* set mcast and pvc flags, stations and multicast servers * are distinct */
if (peer->aa type == MT MAC) vp->vcte flags = VCTEF MCAST CLiE~iT;
else if (local->aa type == AAT MAC) vp->vcte flags = VCTEF MCAST SERVER;
vp->vcte ulp = svc find parsed_ulpO;
ulp tax(vp-~vcte ulp); ~
ASSERT(vp-~vcte ulp != 0);
if (ISVC PARSED~MI DEST UU)) { /* syllllll~Lric ulps */
lu = ~struct Imi ulp *) SVC GET(LMI UU);
} else { /* peer ulp is dfflerent from rocal */
lu = (struct Imi ulp *) SVC GET(LMI DEST UU);
vp->vcte pid = lu->af pid;
vp->vcte~org = lu-~af org;
vp->vcte~aal = lu->af aai;
svc update user info(vp);
vp-~vcte state - VCS C! ~SFn;
vp->vcte qos = SVC PARSED(LMI IQOS SERVICE CLASS) ?
SVC GET(LMI IQOS SERVICE CLASS) svc default qos;
return vp;

/*
-W O 94/07316 5 ' PC~r/US93/08674 ~4~
SVC.C

* create a pvc, used for local creating vcs, signaiing, raw access * etc.
*/
struct vcte *
Ivc create(pc, ctype, cvalue, in, out, peer, local, ulp, atp, aal) struct pcif *pc;
Int in, out;
struct atm addr *peer, *locai;
struct ulptab *ulp;
struct atmif *atp;
int j;
struct vcte *vp;
if (ivpci to vcte(pc, in)) return (struct vcte *) O;
if (in >= IVPCI TAB SiZE) return O;
if (I(vp = svc glob->vcte free)) {
return vp;
}

svc glob->svcstat.vctes++;
pc->pc num vcs++;
ASSERT(VALrD VP(vp)) svc glob->vcte free = vp->vcte next cref; /* upciate free list head */
atrn bzero(vp, seeof(*vp));
vp->vcte cref type = ctype;
vp->vcte~cref~value = cvalue;
i = VCALL HASH(vp->vcte cref value);
vp->vcte next cref = pc->pc vcalltab[il;
pc->pc vcalltab[il = vp;
if (local->aa type l= MT NUUL) vp->vcte local = *loca~
else vp->vcte locai = atm glob->atm null;
vp->vcte peer= *peer;~
t = VPEER HASH(&vp-~vcte peer);
vp->vcte next peer= pc->pc vpeertab[i];
pc-~pc vpeeriab[i] = vp;
vp->vcte pcif= pc;
vp->vcte~pcif->pc ivpci tab[in] = vp;
vp->vcte ivpci = in;
vp->vcte~ovpci = out;
vp->vcte opeak rate = pc->pc opeak rate;
vp->vcte~ulp= ulp;
ulp taX(Urp);
vp->vcte pid = ulp-> ulp pid;

W O 94/07316 2 1 4 4 1 ~ ~ PC~r/US93/08674 .

SVC.C

vp->vcte org = ulp->ulp org;
vp->vcte aal = aal;
vp->vcte~atmlf ~ atp;
svc new state(vp, VCS ESTAB);
retum vp;

svc free vcte(vp) struct vcte *vp;
{

ASSERT(VALID VP(vp));
if (vp->vcte user info) atm free msg~p->vcte user info);
vp->vcte next cref = svc glob->vcte free;
svc glob->vcte free = vp;
svc glob->svcstat.vctes-;
vp->vcte pcif->pc num vcs-;
} UIP free(vp->vcte ulp);~

svc dec(vp) struct vcte *vp;
{
ASSERT(VALID VP(vp));
ASSERT(vp->vcte refcnt >= 1);
-vp->vcte refcnt;
if (vp->vcte refcnt = = 0 && vp->vcte state == VCS CLOSED) {
TR1 (TL1, Usvc dec(%x): deffered free~n~, vp);
} SVC_free_vcte~vp);

return vp->vcte refcnt;
}

svc inc(vp) struct vcte *vp;
ASSERT(VALID VP(vp));
ASSERT(vp->vcte refcnt >= 0);
vp->vcte refcnt++;

* get a free ivpci, does't need to be fast as we only do this as * setup time.
/
vpc~ t svc get ivpci(pc) struct pcif *pc;
..

WO 94/07316 PCI`/US93/08674 2 1 ~ ~P
SVC.C

int i;
for (i = i~il i AST RSVD VCI + 1; i < IVPCI TAB SIZE; i+ +) if (pc->pc ivpci tab[i] -= O) retum i;
retum O;
} ,, * Find the next vcte entry given a local port address (atp), a peer * address and an upper layer protocol and a set of valid states.
* Closed vcte's are delinked from peer hash chain so do not go * looking for closeci vcte's.
*/
struct vcte *
svc find next peer(pc, peer, ulp, np, vstates) struct pcif ~*pc;
struct atm addr *peer;
struct ulptab *ulp;
struct vcte *np;
int vstates;
int j;
jf (!np) {
i = VPEER HASH(peer);
np = pc->pc vpeertab[i];
} else np = np->vcte next peer;
for (; np; np = np->vcte next peer) if (np->vcte peer.aa long[1~ = = peer->aa iong[1 ] &&
np->vcte peer.aa long[O] == peer->aa iong[O] &&
((1 < < np->vcte state) & vstates) &&
ulp== np->vcte ulp) break;
return np;
}
/*
* Find an existing VC b~ n the spec~7ed port ad i,~sses using the * ~pec ~;ed upper layer protocol, ulp, in one of the states, states, * setup on in~,t~ce, pc.
*/
struct vcte *
svc find vc(pc, from, to, ulp, states) struct pcif *pc;
struct atm addr *from, *to;
struct ulptab *ulp;

WO 94/07316 ~ PCr/US93/08674 ~?~
SVC.C

{

struct vcte *vp;
vp = svc find next peer(pc, to, ulp, O, states);
/* get first match *7 while (vp) {
H (ATM ADDR EQ(*from, vp->vcte local)) return vp, vp = svc find next peer(pc, to, atm glob->atm ulp, vp, states); /* get next match */
retum O;
}

/*
* Lookup VC by call re~er~llce and physical i"L~Irace.
*/
struct vcte *
svc find cref(pc, type, value) struct pcif *pc;
int type;
u iong vaiue;
struct vcte *np;
int i;
i = VCALL HASH(value);
for (np = pc->pc vcalltab[i]; np; np = np->vcte next cref) if ((np->vcte cref type == type) &&
(np->vcte_cref value == value)) break;
return np;
3*
* Lookup pcif by port address.
*/
struct pcif *
svc find port(adr) struct atm addr *adr;
struct atmif *atp;
Int i;
for (i = O; i < NNIU; i+ +) {
H ((atp = svc glob->svc pcH[i].pc atmif) &&
ATM ADD~ EQ(*adr, atp->ati port)) retum &svc glob->svc_pcH[i];
return O;
}

W O 94/07316 PC~r/US93/08674 2~4~5ll s c~.c * 8vc close is cailed when a vc ~oes into ciosed state. The vcte is * del"~ l from the cail ,~f~,~nce and peer address hash chains.
svc close(vp) struct vcte *vp;
{

struct vcte *np;
int i;
ASSERT(VALiD VP(vp)) ASSERT(VAUD UU(vp->vcte ulp));
ASSERT(VAUi~ PC(vp->vcte pcif));
svc new state~p VCS_CLOSED);
if (l~vp->vcte flags & VCTEF MCAST SERVER)) vp->vcte p-cif->pc ivpc~ tab[vp->vcte ivpci] = (struct vcte *) 0;
/* delete vcte from call ,t:ier~nce hash chain */
i = VCALL HASH(vp->vcte cref value);
np = vp->vcte pcif->pc vcalltab[il;
ASSERT(np);
if (np l= vp) {
while (np->vcte next cref != vp) np= np->vcte next cref;
np->vcte next cref = vp->vcte next cref;
} else vp->vcte pcif->pc vcalltab[i] = vp->vcte next cref;
/* delete vcte from peer port addr hash chain */
i = VPEER HASH(&vp->vcte peer);
np = vp->vcte pcif->pc vpeertab[il;
ASSERT(np);
if (np != vp) {
while (np->vcte next peer l= vp) np= np->vcte next peer;
np->vcte next peer = vp->vcte next peer;
} else vp->vcte pcif-> pc vpeertab[i] = vp->vcte next peer;
/
* all upper layers currentiy free ,eie,~nces on ICS, but * when they do not then the vcte will have to be free here.
if (vp->vcte refcnt == 0) svc free vcte~vp);
else TR1 (TL1, "svc close(%x): free defferred\n~, vp);

WO 94/07316 2 1 ~ ~ 1 5 ~ Pcr/us93/o8674 ~5 SVC.C
-215' return;
}
/*
* retum a polnter to a port address in one of the atmif structures * linked off tha phsyical inetrtace pc.
struct atm addr *
svc flnd local port(pc port) struct -pcif ~*pc;
{ struct atm_addr *port;
struct atmif *atp;
ASSERT(~/AUD PC(pc));
atp= pc->pc atmif;
while (atp) {
if (ATM ADDR EQ(atp->ati port *port)) return &atp->ati port;
atp = atp-~ati next;
return O;
}

/*
* upper layer protocol routines * The upper protocol table manages Q93S saps or UUs. Upper layer * prulocols register IEEE org/pid palrs In the ulptab using * ulp registerO. When upper payer protocols think they are done * using a ULP they call ulp unregisterO. ulp table entries are * reference counted by svc c routines. When a vcte to ulp l~relence * is created the table entry reference count is i"c,~:",e"l~d.
* i ikewise when a table rer~r~nce is destroyed the refcnt is * dec,~",ellLed.
*

* The protocol running over the ar~ on Iayer is neDoi ed at * col".e~ion setup. SNAP or~,lui dliOI~ and protocol ids are used.
* i~l ,locols which expect need be notified when new circuits are * e~t~bl.shed or when frames arrive on circuits must reglster usin~
* ulp registerO. i~lucols may not un-register. ulp find is used * to lookup a ulptab entry for a given org pid pair. ~his Is fairiy * infrequent as circuits are given pointer to ulptab enrties when * they are ec - ~ -ed.
*/

struct ulptab *
ulp find(pid org) int pid; org;

WO 94/07316 ~ PCI'/US93/08674 2 ~ 4 ~13 ~
o?~
SVC.C
-21~

int ~;
for (I = O; i < NUUS; i++) if (svc glob-> ulptab[i].ulp pid = = pid &&
svc glob-> ulptab[i] .ulp org = = org &&
svc glob- > ulptab[i] .ulp-~ eg;~t~. ~ci) retum &svc glob->ulpta~[l];
return O;
}

ulp alloc p'dO
int i;
for (i = O; i < NUi PS && ulp find(i MI PID NEr ATM + i, LMI ORG Ni_T); i~ +);
return i + iNil PID Ni-T ATM;

* register an upper layer protocoi for aal dispatch on vpci. O
* return indicates no room in the table. otherwise a pointer to the * ulptab entry is retumed. If both org and pid are zero then this * routine ~ r*trs an un-used org/pid within Adaptive Corp s * protocol space.
*/
struct ulptab *
ulp register(org, pid, data, Imi, pcb) int org, pid;
int (*data) O;
int (*Imi) O;
caddr t pcb;
struct ulptab *up;
struct svc globs *sg = svc glob;
if (org > = (1 << 24) 1 I pid > = (1 << 16)) retum O;
if (sg->ulp inuse == NUi PS) retum O;
up = ulp find(pid, org);
if (up) {
if (up->ulp imi == Imi && up->ulp data == data) return up;
else retum O;
for (up = sg->ulptab; up->ulp refcnt > O
up->ulp l :g; )t~l~i, up+ +~

WO 94/07316 ~ 4 Pcr/US93/08674 ~5 SvC.C

if (pid == O && org == O) {
org = IMI ORG NET;
id I -11 -idO
up->ulp rt:y;st~.r~d = 1;
up->ulp~refcnt= 1;
up->ulp~org = org;
up->ulp pld = pid;
up- ulp Iml = Iml;
up->ulp data = data;
up->ulp pcb = pcb;
sg->ulp inuse++;
retum up;

struct ulptab *
ulp ~ y; t~.(ulp) struct ulptab *ulp;
ASSERT(ulp-~ulp ~e~ tered);
ulp->ulp t~ ered = O
ulp free~ulp);

ulp free(ulp) struct ulptab *ulp;
struct svc globs *sg = svc g10b;
if (-ulp->ulp refcnt <= O) {
ASSERT(urp->ulp refcnt == o)-/* atm bzero(ulp sizeof *ulp); */
sg->ulp inuse-;
}

ulp_tax(ulp) struct ulptab *ulp;
ulp->ulp refcnt++;
}

/*
* Called with sevice data units for the signaling VC. However the * s;~ lg vc should never be ~n a state where SDUs are passed. It * has a sepa dle state machie. this may change...
svc mac ImiO

W O 94/07316 ` PC~r/US93/08674 SVC.C

panic(Usvc mac Imi");
}

/*
* release all connecLions sharing the same physicai Interiace as vp.
* Connections already in C! ~:)sFn or WRC are not effected. PVCs are * not .~lea3ed (the signlaing VC is considered a PVC).
*/
svc release all(svp) struct vcte *svp;
struct pcH *pc = svp->vcte pcif;
struct vcte *vp;
int l;
ASSERT(VALID VP(svp));
ASSERT(VALID PC(pc));
for (i = 0; i < VPEERTAB SIZE; i+ +) {
for (vp = pc->pc vpeertab[i]; vp; vp = vp->vcte next peer) {
If (vp == pc->pc s~g) continue-if ((vp->vcte cref type & LMI CREFT~(PE NiASK) == LMI CREi~YPE PVC) continue;
ASSERT(vp->vcte state ! = VCS CLOSED);
if (vp->vcte state <= VCS ESTAB) svc send release ind(vp~;
svc close(vp);
}
}

/*
* This routine handles non-configuration status pdus and sdus.
* Unfortunately this routine Is PYpected to grow as ATM Forum adds * more LMI fu"~ion.~lily. Currenly only vc status requests are * responded to. Re~ ollses are ignored.
svc status(pc, pdu, len, vp) struct pcif *pc;
struct xdu *pdu;
int len;
struct vcte *vp;
{

struct status resp *rdu;
caddr t end;
if (pdu->lmi pdu type == LMI PDU STATUS=NQ) {

WO 94/07316 ~ L PcI/US93/08674 .
SVC.C

switch (pdu-~lmi_status_type) {
case LiVil STATUS VC:
rdu = rstruct status resp *) svc alloc pdu no vp(i~il PDU STATUS RESi', pdu->1mi cref type ~ LMI ~REFD7REcTlof; MASiK, pdu->lmi cref value);
if (rdu = = 0) break;
rdu->lmi status type = pdu-~lmi status type;
end = (caddr t~rdu + sizeof(*rdu~;
if (vp) {
LiMI SET ELEMENT(end, LMI VC STATUS, vp->vcte state);
} else {
LMI SET ELEMENT(end, LMI VC STATUS, VCS CLOSED);
aal send msg(pc->pc sig, O, rdu, sizeofr*rdu) + sizeo~(struct Imi parm));
break;
default:
TR1~TL2, "svc status: unsu~.po,Led status request received, type =%d\n~, pdu->lmi status type);
retum;
}

s{vc_brpO
return;
}

W O 94/07316 P~r/US93/08674 2 1 4 ~
svc.h -22~
/* svc.h * COPYRlGitT 1992 ADAPTIVE CORPORATION
* ALl RIGHTS RESERVED
*/
#ifndef NIU SVC H
#define NIL~SVC H Included #include bytes.h~
#include~svc if.h /*
* atm addr are pdu related definitions are in unipdu.h /
#include unipdu.h~
/*
* Virtaul connection (channel or circuit) table entry.
*

* One entry per conl1e~ Lion. Each entry is linked Into two sepa dle * lists whose heads kept in two hash tables in the pcif structure.
* The call ~r~r~nce lits is used to speed up signaling protocol * lookups. The peer port address list is used to speed up ATM MAC
* lookups when sear .l g for a col~necLion to a particular * de~Li"~liol~.
* Each conneuLion has a pointer to an upper layer protocol table. This * table defines the SNAP encoded protcol identifier a funciton to * be called with sly a li. g serv~ce data units and a function to be * called for incoming frames. ~rhe siy ~; g protocol has an entry * in this table which is how s;~ g PDUs are directed to * svc pdu0. The upper layer pruLocûls manipulate vcte packet * vcte refcnt abd vcte atm~f II e aelvcs. They are includec in this * structure for convene~nce (so the ATM MAC module does not neeci a ~ separate VC table of its own).
*/
struct vcte {
struct vcte *vcte next_cref; /* linked by callref */
struct vcte *vcte~next peer; /* linked by peer adr */
struct ulptab *vcte ulp; /* upper layer protocoi * local b~nd~ng */
struct atm addr vcte local; /* local port address */
struct atm addr vcte peer; /* atm adr of peer */
struct pcif *vcte pcif; /* physical interiace this VC
* uses *7 vpci t vcte ivpc~; /* vci pon which frames are wo 94/07316 ~ 5 ~ Pcr/US93/08674 .

q~5 svc.h * received */
vpci t vcte ovpci; /* vci used from t,~.,s",i~slol1 */
u char vcte state; /* defined in unipdu.h */
u char vcte timeouts; /* number of tlmeouts */
u char vcte ticks; /* number of ticks before * next timeout */
u char vcte cref type; /* direction Is vaiue * t, (lleeldci to be received */
u iong vcte cref value; /* random vaiue */
u char vcte qos; /* vague notion of quaiity is * negu~ ci */
u char vcte i"s~ ce; /* i"c-r~ ,nen~l~i every r ,, ~tlon */
u char vcte user info len; /* length of * vcte user7nfo buffer */
u iong vcte opeak rate; /* outbound peak rate * divideci by 1024 */
u short vcte fiags; /* VCTEF i iCAST illci;c~l~s * multicast vc */
u short vcte cause; /* why this vc dieci */
short vcte refcnt; /* one per lerel~nc;.,g * conn p mte 8 atmif */
struct atmif *vcte atmif; /* atm lan i/f if * appropli~l~ */
caddr t vcte packet; /* used by atm mac to queued * a frame */
caddr t vcte user_info- /* pointer to user info * buffer */
u iong vcte i,uaciwLs;
u short vcte aal u short vcte pid.
u~iong vcte~org;
} u_iong vcte opackets;

/* vcte flags */
#define VCTEF MCAST Ci iENT 1 /* peer address is multicast */
#define VCTEi^ MCAST SERVER 2 /* local address is multicast */
#define VCTEi- CRC32 4 /* add crc32 to each frame, ~ used by ulp */
/* table sizes */
#define IVPCI TAB SIZE (8192+2048) /* indexed by incoming vpcl */
#define VCTA~ SI~E 256 /* maximum number of VCs supprted */
#define ivpci to vcte(pc vci) ((vci < IVPCI TAB SIZE) ? (pc)->pc ivpci tab[vci]: (struct vcte *)0) vpci t get ivpciO;

WO 94/07316 PCI'/US93/08674 ,~
- 2~4~15ll Sw.h #define BITS IN VCHASH 4 #define VCA~:LTAB SIZE (1<<(BITS IN VCHASH)) #define VCALL HASH(crefl VCTABS HASH(cref) #define VPEERTAB SIZE (1~(BITS IN VCHASH)) #define VPEER HASH(adr) VCTABS RASH((adr)->aa long[1 ]) #define VCTABS HASH(value) (((value)^\
''value~>~BlTS IN_VCHASH)^\
'value >>BITS IN VCHASH*2)^\
' 'value > > BITS IN VCHASH*3)^\
value~ > > BIT~IN VCHASH*4)) \
& ((1 < <BITS IN VCHASH)-1)) extern struct vcte *setup indO *get vcteO *os get vcteO;
/*
* Internal Data Units PDU types for timeouts.
*/
#define IDU TO 18 #define IDU MAX Rtl~ltS 19 #define IDU INVALiD PDU 20 /* User VC states */
#define VCS CLOSED 1 /* closed */
#define VCS WSR 2 /* setup recv waiting for upper * layer setup ~esponse */
#define VCS WC 3 /* waiting for connect */
#define VCS WCACK 4 /* waiting for connect ack */
#define VCS ESTAB 5 /* waiting for release */
#define VCS WRC 6 /* waiting for release cor, 'etQ */
/*
* states for siy"ali"g VC.
*/
#define VCS INACTIVE 7 /* should never be in this state */
#define VCS WGRC 8 /* waiting global release complete */
#define VCS WAR 9 /* waiting address reponse */
#define VCS ACTIVE 10 /* signaling com)e-1ion up */
#define VCS LAST VCS ACTIVE
#defineVCS TO VMASK(state) (1<~(state)) #define VCS DATA_IND OK ((1 < <VCS WCACK) + (1 < <VCS ESTAB) + (1 < <VCS INACTIVE) + \
(1 < <VCS WGRC) + (1 < <VCS WAR) + (1 < <VCS ACTIVE~) # d e f i n e V C S N O T D E A D O R D Y I N G
((1 < <VCS WC) + (1 < <VCS ESTAB) + (1 ~ <VCS WCACK) + (1 < <VCS WSR)~
#define V~S DEAD OR DYING ((1<<VCS CLOSED)+(1<<VCS WRC)) W O 94/07316 ~ 1 4 Ll 1 ~ 4 PC~r/US93/08674 -.

Svc.h /*
* upper layer protocol table - * one entry per protocoM~y;~teled to I ,allage virtual circuits which * carried the Illd:cdl~d org and pid in the setup/connect PDUs.
*/
struct ulptab {
int ulp org;/* org nesu~ d at set up */
Int ulp pid;/* protocol id neg ~ cl at setup */
int (*urp Imi) O; /* called when a circuit * state changes */
int (*ulp data) O; /* called when a frame Is * received */
caddr t ulp pcb;/* proLocol speciiic control block */
int ulp refcnt;
Int ulp~~y:~.ter~i, };
#define NULPS 32 extem struct ulptab ulptab[];
struct ulptab *ulp registerO, *ulp findO;
struct svcstat ~
int vctes;
int queued frames;
int msg alioc failures;
int " ,:~.aTi~"ed pdus;
int pdu too brg;
int pciu~lost nomem;
int padding~2];
Int pdus received[LMI PDU_LAST + 1];
int pdus sent[LMI PDU LAST + 11;
int parse causes[GAST CAUSE + 1];
}.

* pcif, one per physical channel, useci by vc layer. We assume one * atm lan per port address assi~ eci to theis physical l,~ tdce. So * pc atmif is used for that purpose. There is a spea~dld i"co", ng * VCT lookup table, pc ivpci tab, per il~ lrdce. Ther is aiso * sepd,dl~ hash chains by peer address and call .~r~,~nce. pc slg * rdrt:r~nces the s~gnal~ng channel.
*/
struct pcif {
u char pc num; /* unit number from i/o system */
u char pc num lans, /* number of ATM LANs * (atmiFs) for this i/f */
u short pc flags;
#define PCIF NIU TO NIU

WO 94/07316 PCI~/US93/08674 5 4 ~6~ ~
Svc.h -.22~
#define PCIF OTHER MAC ADDR IS HIGHER 2 u long pc hw_max mtu; /* maximum MTU h/w supports */
u~ong pc-hw max~vci; /* upper bound on peer * incoming vcl *7 u long pc net max vci; /* upper bound on peer * incomlng vcl *~
u long pc net max vcs; /* limit on number of vc's * network will ailow */
u iong pc net max qos; /* high qos net supports */
u long pc opeak rate; /* o~g ' ,g peak rate of link * divided by 1024 */
u long pc ipeak rate; /* incoming peak rate of link * divided by 1024 */
struct atmif *pc atmif; /* linked list of atm lans */
u char *pc last config; /* last atm lan config pdu */
u short pc last config len; /* last atm lan conflg * pdu-*/-u short pc num vcs; /* current number of vctes * ~c ~ /
struct vcte *pc sig; /* 5i~1 " 19 VC */
struct vcte *pc raw vp; /* vc c-'le ,g all ATM
* cells received */
structvcte *pc vcalltabj'VCAilTAB SIZEl; /*vcte's by call ref */
struct vcte *pc vpeertabjVPEERTAB SIZEl; /* vcte's by peer addr */
struct vcte *pc ivpci tab[lVPCI TAB SIZEl;
};
struct vcte *svc find next peerO, *svc get si!J"~li"g_vcteO, *Ivc createO;
struct vcte *svc~find~crefO, *svc alloc vcte~, *svc find vcO;
struct atm addr *svc flnd local portO;
extern int~ svc backoff['i, svc max retrans[l;
extern int svc ms per tick;
int svc pdu int svc sduO;
vpci t svc get ivpciO;
struct xdu {
struct Imi hdr Imi hdr;
}, struct xdu *svc alloc pduO;
#define PDU Ai iGNED(pdu) ((((int)pdu)&3)==0) extern int svc new ticks[l;
char *svc xdu type strO;

W O 94/07316 2 1 ~ ~ ~ 5 ~ PC~r/US93/08674 -~3 Svc.h -22~
extern int svc pcm;
extem int svc default qos;
extem int hz,- ~
extem int atm nnius[]; /* number of atm lans for each * i"~t,rc~ce */
struct svc globs {
struct pcif *svc pcif;
struct vcte *vcte free;
struct vcte *vcte base;
struct ulptab *ulptab;
int ulp inuse;
struct pcif *svc pcifn;
struct ulptab *sig ulp;
struct svc parm *svc parms;
int svc parrns found;
struct svcstat svcstat;
char *static buf;
};
struct pcif *svc_find portO;
#ifndef RT68K
extern struct svc globs svc globs;
~define svc glob (~svc globs) #else ~define svc glob svc_get globO
struct svc gTobs *svc get globO;
#endif #endif /* NIU SVC H */

W O 94/07316 - PC~r/US93/08674 .

~4 ~5-4 SVC~dU.C

/* svc pdu.c * COPYRlGi-iT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
/*
static char sccsld[l = ~96A96-;
#if Idefined(CERNEL) && defined(RT68i~q #define ERRLOG printdbg #define printf printdbg #endif #include Uatm.hu #include ~svc.h"
#include "unipdu.h~
#include Ydebug.h-#includeYsvc uti.h~
#include~if atm.h~
/* debugging and tracing stuff */
#define TL1 ~define TL2 svc trace> 1 #define TL3 svc trace>2 #define TL4 svc trace>3 #define TL5 svc trace>4 /*
* allocate a generic pdu, given call reference and type.
*/
struct xdu *
svc alloc pdu no vp(type, ctype, cvalue) struct xdu *pdu;
if (pdu = (struct xdu *) atm_alloc msg0) {
pdu->lmi proto = iMI PROTO~:OL;
pdu->lmi pdu type = type;
pdu->lmi cref type = ctype;
pdu->lmi cref vaiue = cvaiue;
return pdu;

* ailocate a generic pdu for a vp struct xdu *
svc alloc pdu(type, vp) W O 94/07316 ~ PC~r/US93/08674 -C?6~ .
SVC pdU.C

int type;
struct vcte *vp;
{ I directlon;
H (vp l= vp->vcte pcif->pc slg) {
direction = (type <= i~ii PDU i AST ? i MI CF~vlRt~ ON MASK: 0);
retum svc alloc pdu no vp(type, vp->vcte cref type ^ direction, vp->vcte cref value);
} else return svc alloc pdu no vp(type, LMI GLOBAL CREF TYPE, Livil GLOBAL CREF VALUE);

* allocate a release pdu for the ~pecif'eci VC.
*/
struct release *
svc alloc release(vp, type, len) struct vcte *vp;
int *len;
{
struct release *pdu;
ASSERT~VAi~D VP(vp)) if ((pciu = (struct release *) svc alloc pdu(type, vp)) == 0) return pdu;
LMI SET Fl F~ iT(&pciu->lmi cause, LMI REi EASE CAUSE, vp->vcte cause);
if (vp->vcte user info) {
struct Imi~uinfo *ui;
ui = (struct Imi uinfo *) ((caddr t) pdu + sizeof(*pdu));
ui->af type= ~MI USER INFO, ui->af~len = vp->vcte user info len;
atm bcopy(vp->vcte user info, ui->af value, vp->vcte user info len);
*len = sizeof(*pdu) + ((sizeof(*u~) - sizeof(ui->af value~ + ui->af len + 3) / 4) * 4;
} else *len = sizeof(*pdu);
return pdu;
}

/*
* allocate a setup or connect for the sF ~ ~- le ~ VC.
struct setup *
svc alloc setup xdu(vp, type, length) struct vcte *vp;
int type;
int *length;
vpci t in, out;
struct setup *pdu, *beg;
char *gcp; /* a pointer for the g,~enhouse WO 94/07316 PCI~/US93/08674 svc pdu.c * cor" ~r */
H (I(pdu = (struct setup *) svc alloc pdu(type, vp))) return 0;
beg = pdu;
ASSERT(pdu->lmi pdu type == type);
pdu->lmi ncalls-~1; ~
svc fill ports(vp, pdu) H (type == LMI PDU SETUP I I type == LMI PDU CONNECl) {
in = vp->vcte ivpci;
out = vp->vcte ovpci-} else H (type == SDU SETUP IND l l type == SDU SETUP CONF) {
out = vp->vcte ivpci, in = vp->vcte ovpci;
gcp = ((caddr t) pdu) + sizeof(*pdu);
H (out) LMI ADD Fl F~ iT(gcp, LMI OVPCI, out);
H (in) LMI ADD ELEMENT(gcp, LMI IVPCI, in);
H (vp->vcte qos l= svc default qos) {
LMI ADD ELEMENT(gcp, LMr IQOS SERVICE CLASS, vp->vcte qos);
LMI ADD ELEMENT(gcp, LMI OQOS SERVICE CLASS, vp->vcte qos);
LMI ADD Fl r~ ~iT(gcp~ LMI OQOS PEAK BW, vp->vcte opeak rate);
LMI ADD ELEMENT(gcp, LMI IQOS PEAK BW, vp->vcte pcif->pc ipeak rate);
H (vp->vcte user info) {
struct Imi~uinfo *ui;
ui = (struct Imi uinfo *) gcp;
ui->af type= ~Ml USER INFO;
ui->af~len = vp->vcte user info len;
atm bcopy(vp->vcte user info, ui->af value, vp->vcte user info ien);
gcp~+ = ((ui->af ien + 5) 7 4) * 4;
H (type == LMI PDU SETUP) {
struct Imi ulp * gcp ->af type = LMI ULP;
struct Imi~ulp * gcp ->af~aal = vp->vcte aal;
struct Imi ulp * gcp ->af pid = vp->vcte pid;
, ,struct Imi~ulp *; gcp; ->af~org = vp->vcte org;
gcp + = sizeof(stnuct Imi urp);
*length = Sicp- (caddr t) beg;
return beg;
}

/*
* send a release */
svc send release pdu(pc, pdu, len) struct pcH *pc;

WO 94/07316 2 1 4 ~ PCr/US93/08674 svc pdu.c struct release *pdu;
Int len;
{

struct release *pdu0;
if (len < sizeof *pdu) {
pdu0 = (struct release *) atm alloc msgO;
if (!pduO) {
atm free msg(pdu);
retum;
*pdu0 = *pdu;
atm free msg(pdu);
pdu = pdu0;
pdu->lmi cref type^= LMI CREFDIRECTION MASK;
pdu->lmrpdu type = LNil PDU RELEASE-LMI SET~I FFl-'\iT(&pdu->lmi cause, LMI RELEASE CAUSE, INVALiD CALL REF);
aal send msg(pc->pc sig, O, pciu, sizeof(*pdu));
return Q;~
}

/
* send a release and initiate local release if applo,~ e */
svc reject pdu(pc, pdu, len, vp) struct pcif *pc;
struct release *pdu;
int len;
struct vcte *vp;
{

struct atmif *atp;
if (!vp) {
pdu->lmi pdu type = LAAil PDU RELEASE;
ASSERT(pdu->lmi cause.a~ type == LMI RELEASE CAUSE);
aal send msg(pc->pc sig, 0, pdu, sizeof~pdu));
return O;
} else if (vp->vcte state < VCS WRC) {
#ifndef lint int dummy;
LMI GET Fl F' ~-NT(8Lpdu->lmi cause, vp->vcte cause, dummy);
#endif svc new state(vp, VCS WRC);
svc send l~lease(vp);
svc send release ind(vp);
} else if (vp >vcte state > VCS WRC) { /* PCM states */
svc new state(vp, VCS WGRC);
svc release all(vp);
svc send release(vp);
for~atp -~pc->pc atmif; atp; atp = atp->ati next) atm delete ian(atp);

PC~r/US93/08674 2~4~15~ svc pdu.c atm free msg(pdu);
return 0;~
}

struct setup *svc alloc setup xdu0;
svc send setup(vp) struct vcte *vp;
int len;
struct setup *pdu;
ASSERT(VAilD VP(vp));
if (pdu = svc alloc setup xdu(vp, LMI PDU SETUP, &len)) aal send msg(vp->vcte pcif->pc s~, 0, pdu, len);
}

svc send setup_ind(vp) struct vcte *vp;
int len;
struct setup *pdu;
ASSERT(VALID VP(vp));
~ (pdu = svc a~ioc_setup xdu(vp, SDU SETUP IND, &len)) (*vp->vcte~ulp->ulp Irni) (vp, pdu, len);

svc send setup conf(vp) struct vcte *vp;
Int len;
struct setup *pdu;
ASSERT(VALID VP(vp));
if (pdu = svc alloc setup xdu(vp, SDU SETUP CONF, &len)~
(*vp->vcte ulp-> ulp Irni) (vp, pdu, len);

svc send setup comp(vp) t- t -t *
struct xdu *pdu;
ASSERT(VALID VP(vp));
if (pdu = (struct xdu *) svc alloc pdu(SDU SETUP COMP, vp)) (*vp->vcte ulp->ulp Imi) (vp, pdu, ~k~pdu)), return;
}

W O 94/07316 ~ 1 ~ 4 1 ~ ~ PC~r/US93/08674 ~69 !
svc pdu.c svc send conne~(vp) struct vcte *vp;
struct setup *pdu;
Int len;
ASSERT(VALID VP(vp)) If (pdu = svc aTloc setup xdu(vp, i- MI PDU CONNECT, 81en)) aal send msg(vp->vcte pcH->pc sTg, 0, pciu, len);
svc send cack(vp) struct vcte *vp;
struct connect ack *pdu;
ASSERT(VAUD VP(vp));
if (pdu = (struct connect ack *) svc ailoc pdu(i MI PDU CONNECT ACK, vp)) aal send msg(vp->vcte pcif-~pc sig, 0, pdu, skeof(*pdu));
}

svc send release comp(vp) struct vcte *vp;
struct release comp *pdu;
ASSERT(VALiD VP(vp));
Tf (pdu = (struct release comp *) svc alloc pdu(LNil PDU REi EASE COMP, vp)) aal send msg(vp->vcte pcif->pc sig, 0, pdu, sizeof( pdu));
}

svc send release(vp) struct vcte *vp;
struct release *pdu;
int len;
ASSERT(VAi iD _ VP(vp));
if (pdu = svc alloc release(vp, iMI PDU REi EASE, &len)) aai send msg(vp->vcte pcTf->pc sig, 0, pdu, len);
svc send release_ind(vp) struct vcte *vp;
{
int len;
#Tf 0 struct release *pciu;
ASSERT(VAi iD VP(vp));
if (pdu = svc aTioc release(vp, SDU REi EASE IND, 81en)) (*vp->vcte ulp-> ulp iml) (vp, pdu, len);
#else struct setup *pdu;
r WO 94/07316 PCI`/US93/0867~
~ 1 4 ~ .?70 Svc_pdu.c caddr t cp ASSERT(VAi iD VP(vp)) if (pdu = (struct setup *) svc alloc pdu(SDU REi EASE iND, vp)) {
svc fill ports(vp, pdu);
cp - ~addr t) & pdu[1];
Lll/il ADD rrr~ T(cp~ LMI REi FASE CAUSE, Vp->VCtQ cause);
len - cp- (caddr t) pdu;
(*vp->vcte ulp-~ ulp -imi) (vp, pdu, len);
#endH
}

svc fill ports(vp, pdu) struct vcte *vp;
struct setup *pdu;
H (vp->vcte cre~ type & iMI CREFDIRECTION MASi~ {
pdu->lmi caller = vp->vcte local; /* we inltiated setup */
pdu->lmi callee = vp->vcte peer;
} else {
pdu->lmi callee = vp->vcte iocal; /* peer initiated setup */
pdu->lmi caller = vp->vcte peer;
}

WO 94/07316 2 1 4 ~ L PCr/US93/08674 -~1 SvC utl.C
.
/* svc.uti.c * COPYRlGi-iT 1992 ADAPTIVE CORPORATION
* ALL RIGHTS RESERVED
*/

~ *
* This file cor,t~L ,s svc utility and pdu parsing routines.
*/

static char sccsid[l = ~%A%-;
#if Idefined(CERNEL) && defined(RT68i~
#define ERRLOG printdbg #define printf printdbg #endif #ifdef notdef #include Uall.hu #IncludeUip errs.hU
#include ~unsp.hU
#endif /* notdef */
#include Uatm.hu #include ~svc.hU
#include Uunipdu.hu #include Udebug.hu #include Utrace.hu #includeUsvc utl.h"
extern int svc trace;
#define TL2 svc trace>1 char *svc xdu names[] = {Uunknownu~usetup~,uconne~,~connect_ack /* 4 */ Ustatus enquiry~, ~status rt:spol1s~ eas~ release cor., ' /* 8 */ "setup request~, ~setup l~sponse~, ~release requesr, ~status requestU~
/*12 */~release i,~ lonU~ Usetup cor"' ~, Usetup c~nfirm, ~known sdu~, /* 16 */ "setup illdic~liol,~, Ustatus ,t,sponse~, ~timeou~, ~max retries /* 20 */ -invaiud pdu~};

char *
svc xdu type str(type) u int~ ~type;
if (type < IDU INVALiD PDU) retum svc_xdu_names[tYPel;

~144~5~
svC utl.c -~4 else return svc xdu names[O];

char *
svc pdu_type str(type) u int type;
H (type < LMI PDU LAST) return svc xdu n~,l,es[lype];
else retum svc xdu names[O];

svc valid_sdu_type(type) if (type ~ SDU SETUP REQ 1I type > SDU STATUS RESPIl type == 15 /* I */ ) return O;
retum 1;
}

svc valid pdu type(type) if (type < LMI PDU SETUPIl type > LiVii PDU LAST) retum O;
return 1;
}

char *
svc e1 64_ntoa(adr) struct atm addr *adr;
u char *cp = (u char *) adr;
sprinff(svc glob->static buf ~%x:%x:%x:%x:%x:%x:%x:%x cp[O] cp[1 ] cp[2] cp[3]
cp[4] cp[5] cp[6l cp[7]);
return svc glob->static buf;

/*
* parse pdu returns the event coort:~ponding to the pdu type. In * addition global flags are set to r~f :rt:nce the par~",~l~l;, in the * pdu. If there is any problem with the PDU this routine should * catch it. This just checks static pdu valldity for protocol * violalions. A zero return l,ldicales ths pdu does not violate any * encoding rules. Caller and cailee adci,t:~ses are checked as they * are considered static. The vci s are not checked as they are * subject to pdu specific nPgo ~liol1.

WO 94/07316 ~ ~ 4 4 1 ~ ~ Pcr/us93/08674 , .
~3 SvC utl.c .
*/
/* F~ "ly was moved to svc.h to give other files access to it */
#ifndef notdef #define CON Ei EMS ((1~ ~LMI iVPCI) + (1 ~ dMI OVPCI) + (1~ <LMI USER_INFO) + (1 < <LMl_iQOS PEAK B\N~
(1<<LMI OQOS PEAK BW~+(1<<LMI iQOS SERVlCE_CLASS)+(1<<LMil_OQOS_SERViCE CLASS)) #endif /* NOT notdef */
Int setup vaiid elems = -1 /* CON ELEMS+(1<<LMI ULP) */;
int connect valJd elems = -1 /* C~N ELEMS */;
int release vaild elems = (1 << LMI RELEASE CAUSE) + (1 << iMI USER iNFO);
int no valid elems = 0;
Int valld lesponse elems[LMI STATUS NTYPES] = /* indexed by status type */ {
(1 << LMI CONFIG ENQ) I (1 <~ LMI CONFIG RESP) I (1 << LMI _ PORT ADDR), 0, 0, 0, 0, 0};
int vaiid enquiry elems[LMI STATUS NTYPES] = /* indexed by status type */ {
(1 < < LMI CONFIG ENQ), 0, 0, (1 < < LMI VC STATUS), 0, 0};
svc parse xdu(pc, pdu, len) struct pcif *pc;
struct xdu *pdu;
int len;
{

int reason;
reason = svc parse xdu real(pc, pdu, len);
K (reason) {
TR1(TL2, Usvc parse xdu0 ->%d\nU, reason);
svc trace pdu(pdu,ren, 1, pc->pc sig->vcte ivpci);
return reason;
}

svc parse xdu real(pc, pdu, len) struct pcif *pc;
struct xdu *pdu;
int len;
{ ~nt reason = O;
struct port addr elem *pae;
int J;
int swap pdu;
#ifdef little endian 7 if (pdu->lmi pdu type <= LMI PDU LAST) {
OS REVi_RSE32(pdu->lmi cref value);

WO 94/07316 PCI~/US93/08674 2 ~ .5 ~
svC utl.C

swap pdu= 1;
} else ~
#endif swap pdu = 0;
ASSERT(PDU AUGNED(pdu));
/* validate call ,~rt:rt:nce K not sdu setup request */
if ((pdu->lmt cref type & Ll~il CREFTYPE MASi9 != i MI CREFTYPE SVC &&
(pdu-> Imr cref type & UMr CREFTYPE MAS19 1 = UMr CREFTYPE PVC &&
(pdu-~lmi~pdu type l= SD-U SETUP REQ)) return INVA~iD CAU REF;
/*
* reverse caller/callee for multicast when stations are back * to back */
if (pc-> pc flags & PCIF NIU TO NIU) ~
N ((pdu->lmi pdu type =- iM~ PDU CONNECT &&
((struct setup *) pdu)->lmi caller.aa type == MT MAC)) svc fixup mcast connect(pc, pdu);
else if (pdu->lmi pdu type = = UMI PDU SETUP &&
((struct setup *) pdu)->lmi - ~e ~ type = = MT MAC) svc fixup mcast setup(pc, pdu);
switch (pdu->lmi pdu type) {
case U~il PDU SETUP:
case SDU SETUP RESP:
if (!svc valid peer port(&((struct setup *) pdu)->lmi caller)) return INVALiD SRC ADDR-H (((struct setup ~ pdu~->lmi ncalls l= 1) return INVAUD MSG ELEMENT;
reason = svc set opts~caddr t) pdu + skeof(struct setup), len - skeof(struct setup), pdu->lmi pdu type == Uvil PDU SETUP ?
setup valid elems: connect vai'd elems, swap pdu);
H (pdu->lmi pdu type == LMI PDU SETUP &&
Isvc find parsed ulp0) return ULP UNAVAllABUE;
break;
case SDU SETUP REQ:
case LMI PDU CC5NNECT:
H (Isvc valid_peer port(&((struct setup *) pdu)->lmi cailee)) return INVAUD ~RC ADDR;
H (((struct setup ~ pdu~->lmi ncalls != 1) return INVAUD MSG Fl ~ T;
reason = svc set opts~caddr t) pdu + skeof(struct setup), len - skeof(struct setup), pdu->lmi pdu type == SDU S_TUP REQ ?

WO 94/07316 2 ~ 4 '~ 1 5 ~ PCI/US93/08674 .

SVC utl.c ~7-setup vaiid elems: connect valid elems, swap pdu);
if (pdu->lmi pdu type == LA7il PDIJ CoNNECf8&
I(SVC PAI~SED~LMI IVPCI) &~ SVC PARSED(LMI OVPCI))) return Fl F''-NiT MISSING;
break;
case SDU STATUS REQ:
case LMI PDU STATUS ENQ:
if (pdu->lmi status type >= LMI_STATUS_NTYPES) return UN~NOWh MSG;
reason = svc set opts((caddr t) pdu + sizeof(struct xdu), len - sizeof(struct xdu~, valid enquiry elems[pdu->lmi status type - LMil STATUS CONFIG], swap pdu);
ff (pdu->lmi status type == LiVII STATUS CONFIG) {
if (ISVC PARSED(LMI CONFIG ENQ)) return Fl F"-~iT Ml-SSING;
if (((struct config erem *) SVC GET(LA~ CONFIG ENQ))-~af version l= LMI VERSION) {
svc report versron conflictO;
return LMI-VERSIO-N CONFLICT;
} }
break;
case iMI PDU STATUS RESP:
if (pdu->lmi status type >= iMI STATUS NTYPES) return UN~NOWh MSG;
if (reason = svc set opts((caddr t) pdu + sizeof(struct xdu), len - sizeof(struct xdu), valid ~spol~se elems[pdu->lmi status type - LMI STATUS CONFIG], swap pdu)) {
svc_brp(pdu, reason);
break;
}

switch (pdu->lmi_status type) {
case LMI STATUS CO~IG:
if (ISVC PARSED(LMI CONFIG ENQ) ISVC PARSED(LMrCONFlG RESP)) retum Fl F~ IT Mi~;SING-H (((struct config erem *) SVC GET(LI~I CONFIG RESP))->af version l= LMI VERSION) {
svc report versron conflict0-return LMI VERSIO-N CONFLICT;
if (SVC PARSED(LMI PORT ADDR)) {
* port addr elei~ s must be * contiguous */
pae = (struct port addr elem *) SVC GET(LMI PORT ADDR);
for 'J = 0;
< svc glob->svc parms[LMI PORT ADDR].par ndups;
++, pae++) 4 .?~G
SvC Utl.c if (pae[11.af type != LMI PORT ADDR) return INVALID MSG ELEMENT;
}

break;
case LMI STATUS VC:
If (ISVC PARSED(LMI VC STATUS)) return Fl F"-'~IT MrSSING;
break;
default:
reason = UNKNOWN MSG;
}

break;
case LMI PDU CONNECT ACK:
case LMI PDU RELEASE COMP:
reason~- svc set opts~caddr t) pdu + sizeof(struct xdu), len - sizeof(struct xdu~, no valid elems, swap pdu);
break;
case SDU RELEASE REQ:
case LMI PDU RELEASE:
reason - svc set opts((caddr t) pdu + sizeof(struct xdu), len - sizeof(struct xdu~, release valid elems, swap pdu);
break;
default:
ASSERT(0); /* should not get here */
return UNKNOWN MSG;
}

return reason;
}

/*
* This routine fixes up multicast setup/connect when back to back * nius are si~ lillg to that we go throught the promiscuous mode * setup logic. The callee (multicast) is moved to the caller. A
* local port address for the interface is copied into the callee * address. The lanid from the last byte ~s copied.
*/
svc fixup mcast setup(pc, pdu) struct p-cif *pc;
struct setup *pdu;
int lan;
struct atmif *atp;
lan= pdu->lmi caller.aa lannum;
pdu->lmi caller= pdu->~mi callee;
for (atp - pc->pc atmif; atp, atp = atp->ati next) {

WO 94/07316 ~ 1 4 ~ Pcr/us93/o8674 .?r7 SVC utl.c if (atp->ati port.aa iannum == lan) {
pdu->lmi callee = atp->ati port;
pdu->lmM- -"e~ ~ iannurn = lan;
return;
Ir }
} /* else we will fall later as no * local port adci,~sses are deflned */
}
/*
* peer is sending a connect back (we are back-to-back) with his port * adr as the callee and the mcast adr as the caller. we need to put * our port adr as the caller and the mcast as the callee.
*/
svc fixup mcast connect(pc, pdu) struct pcif *pc;
struct setup *pdu;
int lan;
struct atmif *atp;
Ian = pdu-> Imi - " - e ~ lannum;
pdu->lmi callee = pdu->Tmi caller;
for (atp - pc->pc atmif; atp, atp = atp->ati next) if (atp->ati port.aa lannum == lan) {
pdu-~lmi caller - atp->ati port;
pdu->lmi~caller.aa iannurn = lan;
return;
} /* else we will fail later as no * local port adclresses are defined */

svc valid peer port(port) struct atm addr *port;
if (port->aa type == MT MAC) /* if MAC addr then must be multicast */
return port->aa bytelATM FIRST MAC] & 0x1;
else if (port->aa_type l= MT PORF) return 0; /* not mac, not port, then invaiid */
retum 1; /* not very selective */

* If there was a source ulp then return ulptab entry for it (if * found) otherwise return ulptab entry for iMI UU. LMI SRC ULP
* only appears in SDU Si~UP REQ SDUs. When parsing them we want to * verify that there is a SDU handler for this curcuit. i-~l SRC UU
* allows different Ui Ps on each end of a cc,-nection.
I

W O 94/07316 ` PC~r/US93/08674 2 ~ 5 ~
svc utl.C
~40 */
struct ulptab *
svc find parsed ulp0 if (SVC PARSED'LiVII UU)) return ulp find ((struct Imi ulp *) svc glob->svc parms[ilVil UU].par ptr)->af pid, ((struct Im ulp *) svc-glob->svc parms[LI~ ULPl.par ptr)->af org);
else return 0;
}

struct svc parm svc parms[iMI LAST Fl F~' '`iT + 1] = {
"no elementU, 0, 0}, {~relasra~cause~, 4, 0}, - "ivpcl~, 4, 0}, {~ovpcl~, 4, 0}
"iqos peak bw~, 4, 0}, {~iqos ave bw~, 4, 0}, uiqos peak dur~, 4, 0}, {"iqos priority~, 4, 0}, Uoqos pear bw", 4, 0}, {~oqos ave bw~, 4, 0}, "oqos peak dur~, 4, 0}, {"oqos proTri~, 4, 0}, - "ulp", sizeof~struct Imi ulp), Li~il PAR REFERENCE}, -"user infoU, 4, i-MI PAR REFERENCE~, "confrg enq", skeof(struct config elem), LNI PAR REFERENCE}, Uport add~s~, skeof(struct port addr elem~ LNirPAR kt~t~tl~JCE}, - "conflg resp~, sizeof(struct config elem~, LMI PAR kLI L~LNCE}, "dest u~p", sizeof(struct Iml ulp), iMI PAR REFERENcE}~
-"vc status", 4, 0}, };
int svc parms size = sizeof(svc parms);

* svc set opts0 extracts optional pardrllaL~ from xdu's and places * them in the svc parms structure. The values in svc parms are oniy * valid until svc set opts0 is cailed again or the buffer being * parsed is IllodUied or freed. svc swap optsO performs byte swap * operations on fields of the pdu whlch are not P~cesseci via * add/get/set element ulacll)es. Those .llacloes perform the byte * swapplng as the pcius are built / parsed. svc swap pdu is called * illlllledialely after a signaling pdu is received and ~ust prior to * I-~ns.l.:~,sion. atm addr structures are always kept in network * order so no 6W, ,- 19 Ts required. d~llr~ asllo is the only * routine which mucks about with atm addr structures and it takes * ~ polls;bility for getting the bytes right. Only PDUs are sv:~pped * from network order to host order.
*/
svc set opts(cp, left, valid elems, swap pdu) u char *cp;

WO 94/07316 2 ~ 4 4 ~ ~ 4 PCr/US93/08674 -~79 svc utl.c ~7,1 int i;
struct svc parm *par;
u char *ep = cp + left;
svc glob->svc parms found = O;
H (swap pdu) svc swap opts(cp, left);
while~cp ~ ep) {
if (*cp > UMI LAST EUEMENT l l (valid elerns & (1 < < *cp)) = = O) retum~NVAUD MSG Ei-,EMENT;
par = &svc glob->svc parms[*cp];
if (ieft < par->par size~
retum INVAUD MSG Fl '''-NT;
if (svc glob->svc parms found & (1 << *cp)) {
/* dup, Just count and skip */
if (++par->par ndups <= par->par max dups) return INVALi-D MSG Fl F'~
} else {
svc glob->svc parms found l= (1 << *cp);
par->par ndups = O;
if (par->par flags 8, i- MI PAR I~LI Ll~tl',iCE) par->par ptr = (caddr t) cp;
else LMI GET Fl FA''~\iT(cp, par->par vaiue, i);
}

if (*cp == LMI USER INFO) {
i = cp[1];
if (i > LMI MAX UINFO l l cp + i ~ ep) retum liNVAUD MSG Fl F~A~'NT;
cp += ((2 + i + 3) / 4~* 4;
} else cp += par->par size;
return o;

* svc swap optsO - this routine swaps all non Imi parm l,ien,t:, t~.

svc swap opts(cp, left) u char *cp;
int left;
{

int 1, type;
struct svc pamn *par;
u char *ep = cp + left;
while (cp < ep) {
I

W O 94/07316 . PC~r/US93/08674 ~0 SvC utl.c -~42-/* if af type is invaiid */
H (*cp > LMI i~ST Fl -M-NT) return INVA~iD i~SG Fl ~'~ NT;
par = &svc glob->svc parms[*cp]; /* get parrn table * pointer for this type */
if (ieft ~ par->par ske) return INVALiD MSG ELEMENT; /* elem does not fit in * p~iu */
* Now switch on the af type field and swap the * non-byte A~cesssecl ~ .ds within the structure type = *cp, /* get element type */
if (type == LMI ULP l l type == LMI DEST ULP) {
OS REVERSE16(((struct Imi ulp *) cp)->af pid);
OS REVERSE32(((struct Imi ulp *) cp)->af or3);
} else if (type == LMI CONFIG ENQ l l type == LNil CONFIG RESP) {
OS REVERSE16( (struct config elem *) cp)- af max qos);
OS REVERSE32( (struct config elem *) cp)->af max vci);
OS REVERSE32( (struct config elem ~) cp)->af max vcs);
} else if (type == L~il PORT ADDR) {
OS REVERSE16(((struct port addr elem *) cp)->af mld);
OS REVERSE16(((struct port addr eiem *) cp)->af mcasts);
OS REVERSE32(((struct port addr elem *) cp)->af mtu);
if (*cp = = LMI USER INFO) {
i = cp[1];
if (i > LMI MAX UINFO l l cp + i > ep) return INVALI~ MSG ELEMENT;
cp + = ((2 + ~ + 3) / 4~* 4;
} else cp += par->par slze;
return 0;
}

char *
svc cause to str(cause) _ _ switch (cause) ~
case UASSIGNED SRC ADDR:return ~UASSIGNED SRC ADDR;
case UASSIGNED DST ADDR:
return~UASSlGNED DST ADDR;
case NO DESTINATION ROUTE:
return~NO DESTINATION ROUTE;
case VCI UN-ACCEPTABLE:
return ~VCI UNACCEPTABLE;

WO 94/07316 2 ~ 4 ~ 1 ~ I P~/US93/08674 2~
SVc utl.C
-~
case NORMAL RELEASE:
return~NORMAL RELEASE";
case NO ANSWER FROM USER:
return~NO ANSWER FROM USERU;
case VC IDLE:
retum~VC IDUE~;
case VC REDUNDANT:
return~VC REDUNDANT-;
case NO VCI AVAIL:
return rNO VCI AVAIL~;
case NETWORK I~NAVAIL:
return~NETW~iRK UNAVAIL~;
case TEMPORARY FAILURE:
return~TEMPORARY FAILURE~;
case NO RESOURCES-returnrNO RESOURCES~;
case QOS UNAVAILABUE:
return"QOS UNAVAILABUEU;
case UU UNAVAILABLE:
return ~LP_UNAVAILABLE";
case INVAUD CALL REF:
return"lNVALlD CALL REFU-case INVALID SR~ ADDR:
returnUlNVALlD SRC ADDR~;
case INVALID DST ADDR:
return~lNVAUD DST ADDRU;
case INVALID MSG ELEMENT:
return"lNVALlD MSG ELEMENTU;
case ELEMENT MlSSlNG:
return ~FI F"~NT MISSING";
case INVALID STATE:
return"lNVALlD STATEU;
case INVALID Sl~/CI:
returnUlNVA~lD SIGVCI";
case UNKNOWN MSG:
return"UNKNOWN MSGU;
case UNSUPPORTED SERVICE:
return"UNSUPPORTED SERVICE~;
case PROTOCOL ERR:
return~PROTOCOL ERR~;
case NETWORK TIMEOUT:
returnUNETWORK TIMEOUT~;
case LMI VERSION CONFUCT:
return irUMI VERSION CONFUCT~;
default:
return "unknown causeU;
}

5 ~
SvC Utl.c -~44 /*
~ svc log new_stateO maintains a circuiar buffer of VC state * i.lfu.,na~on. The cause, time, call r~ nce, port or card, * caller/callee add-t:~ses are logged. Logging may be disabled by * setiing svc riog to zero.
*/
Int svc rlog enabled = 1;
vold svc log new state(vp, new state) struct vcte *vp;
{ register struct svc_riog *s;
if (!svc rlog enabled) return;
s = (struct svc riog *) tr get entry(skeof *s);
f (!s) return;
s->thdr.subsystem = SVC STATE LOG;
s->thdr.sss = vp->vcte pcif->pc num;
- s->thdr.length = sizeofr*s);
s->new state = new state;
s->timeouts = vp->vcte timeouts;
s->old state = vp->vcte state s->cref type = vp->vcte~cref type;
s->cref~value = vp->vcte cre~ value;
s->cause = vp->vcte cause; ~
s->caller = vp->vcte~ocal s->callee = vp->vcte peer;
s-> ipackets = vp->vcte Ir~4e~s:
s->opackets = vp->vcte op~kets:
atm settime(s->time); ~
retum;
}

#Wef little endian svc swap pdu(pdu, len) struct xdu *pdu;
int len;
int reason = O;
struct port addr elem *pae;
int ~ J;

/*
* Ail pdus have an Imi hdr. The only thing in the header * that must be swapped is the u long Imi cref value. Do it * now.

WO 94/07316 ~ 1 4 ~ Pcr/US93/08674 .?~3 SVC Utl.c -~
*/
OS REYERSE32(pdu->lmi cref vaiue);

/*
* I think that I only need to convert LMI pdus vs SDU pdus.
* I believe that SDU pdus are gene,dlaci locally or are * ~"o~iired versions of allready converted LMI j-~dus.
*/
switch (pdu->lmi pdu type) {
case i-JUil PDU SETUP:
* The setup pdu has an Imi hdr (aiready s~:apped * above), two atm addr (already in correct byte * order bec~ e they are written vla byte ~cesses * and possi~e optional Imi parms */
case U~til PDU CONNECT:
/*
* NOTE Iml ivci and Imi ovci are acctually treated * just like Imi parms. Therefore swapped via * LMI GET E-LEM and LMI SET ELEM. So ... just skip * over a setup size struct to get to "a-'c" ~di * opts.
*/
svc swap opts((caddr t) pdu + slzeof(struct setup), len - sizeof(struct setup));
break;
case LMI PDU STATUS ENQ:
case LiMI PDU_STATUS RESP:
case LMI-PDU CONNE~T_ACK:
case LMI_PDU RELEASE COMP:
case LMI PDU RELEASE.
/* status enq is just an Imi hdr addlional opts */
svc swap opts((caddr t) pdu + sizeof(struct xdu), len - skeof(struct xdu));
break;
default:
break;
}

return;
#endif /* little endian */

WO 94/07316 PCr/US93/08674 15 ~ vlm.c /* ~im.c * COPYRIGHT 1992 ADAi'TlVE CORPORATION
* ALL RlGtiTS RESERVED
*/
* Des.;,i~.tiol,:
* <Des~ ion of the generai category of file collt~:rlt~>
* Routines:
* ~An OPTIONAL 11st su"""~,k~l,g the routines In this file>
AAAAAAAAA~.AAAAAAAAAAAAAAAAAAAAAtNL~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
~Kdef UNIX
#include <signal.h>
f{rapo } print_my_tcbo;
main(argc argv~
int argc;
char *argv[];
{
Envlnit(argc argv);
OpenComm(MHW l~etS~ctldO, GetGenericO);
signal(SlGUSR1 frap);
Im malnO;
}
ML SAP CreateO
return (1);
}

Mi DataSendNR(key data len prefix, atm hdr) Int *key;
short *data;
int len;
int prefix;
int *atm hdr;
{

retum (1);
}

#endif

Claims (34)

1. A communication system comprising, an ATM network having a plurality of ports, each port having a unique port address, and said ATM
network including one or more ATM switches for con-necting sending ports to receiving ports, a plurality of stations, each station having a unique station address distinguishing the station from other stations, each station connected to the ATM network at a port whereby source stations commu-nicate with destination stations, each station including, packet means for providing packets for transferring information, said information including a destination station address for addressing destination stations, packet converter means for converting between packets and cells for transfers between stations, address resolution means for determining a port address corresponding to a destination station ad-dress, said address resolution means including multicast means for multicasting the destination station address to a group of said stations, management means for requesting connections through said ATM network connecting sending ports to receiving ports whereby packets are transferred from source stations to destination stations by cell transfers through said ATM network.
2. The system of Claim 1 wherein said ATM network includes means for connecting a sending port to many receiving ports.
3. The system of Claim 1 wherein said management means includes means for transfering configuration parameters between stations and said ATM network.
4. The system of Claim 3 wherein said management means includes means for transfering multicast configuration parameters between stations and said ATM network.
5. The system of Claim 1 wherein said management means includes means for transfering unicast configu-ration parameters between stations.
6. The system of Claim 1 wherein said multicast means includes, response means for providing the receiving port address for a destination station, reply means for transmitting the receiving port address to the sending port through said ATM network.
7. The system of Claim 6 wherein said reply means includes, means for establishing a port-to-port connection between a destination station at the receiving port and the source station at the sending port.
8. The system of Claim 1 wherein, said multicast means includes, response means for providing the receiv-ing port address for a destination station, reply means for establishing a port-to-port connection between the destination station at the receiving port and the source station at the sending port, and said management means including means for trans-mitting cells between said source station and said destination station over said port-to-port connection.
9. The system of Claim 1 wherein said group of stations that receive the multicast destination station address constitute a local network and wherein said ATM network includes, local network management means for controlling the stations that are included within said group of stations that receive the multicast destination station address.
10. The system of Claim 9 wherein said local network management means includes a station table for storing station addresses for indicating the stations that are included within the local network.
11. The system of Claim 10 wherein local network management means includes, means for adding and deleting a station address to said station table for adding and deleting, respectively, stations to and from the local network.
12. The system of Claim 11 wherein each station includes, means for communicating with said local network management means for communicating that the station is included in said local network.
13. The system of Claim 9 wherein said local network management means includes a port table for indicating the ports that are included within the local network.
14. The system of Claim 13 wherein local network management means includes, means for adding and deleting a port address to said port table for adding and deleting, respective-ly, ports to and from the local network.
15. A communication system comprising, an ATM network having a plurality of ports, each port having a unique port address and said ATM
network including an ATM switch for connecting sending ports to receiving ports, a plurality of stations, each station having a unique station address distinguishing the station from other stations, each station connected to the ATM network at a port whereby source stations commu-nicate with destination stations, each station including, packet means for providing packets for transferring information, said information including a destination station address for addressing destination stations, packet converter means for converting between packets and cells for transfers between stations, means for establishing a plurality of groups of stations, each group constituting a local network of the stations in the group, address resolution means for determining a port address corresponding to a destination station ad-dress, said address resolution means including multicast means for multicasting the destination station address from a source station to the local network of stations for the group of stations includ-ing the source station, management means for requesting connections through said ATM network to connect sending ports to receiving ports whereby packets are transferred from source stations to destination stations by cell transfers through said ATM network.
16. The system of Claim 15 wherein said ATM network includes means for connecting a sending port to many receiving ports.
17. The system of Claim 15 wherein said management means includes means for transfering configuration parameters between stations and said ATM network.
18. The system of Claim 17 wherein said management means includes means for transfering multicast configuration parameters between stations and said ATM network.
19. The system of Claim 15 wherein said management means includes means for transfering unicast configu-ration parameters between stations.
20. The system of Claim 15 wherein said multicast means includes, response means for providing the receiving port address for a destination station, reply means for transmitting the receiving port address to the sending port through said ATM network.
21. The system of Claim 20 wherein said reply means includes, means for establishing a port-to-port connection between a destination station at the receiving port and the source station at the sending port.
22. The system of Claim 15 wherein, said multicast means includes, response means for providing the receiv-ing port address for a destination station, reply means for establishing a port-to-port connection between the destination station at the receiving port and the source station at the sending port, and said connection means including means for trans-mitting cells between said source station and said destination station over said port-to-port connection.
23. The system of Claim 15 wherein said ATM network includes, local network management means for controlling the stations that are included within each of said groups of stations that form local networks.
24. The system of Claim 23 wherein said local network management means includes a port table for indicating the ports that are included within the local network.
25. The system of Claim 24 wherein local network management means includes, means for adding and deleting a port address to said port table for adding and deleting, respective-ly, ports to and from the local network.
26. The system of Claim 15 wherein said ATM network includes, local network management means for transmitting the port address controlling the stations that are included within each of said groups of stations that form local networks.
27. The system of Claim 26 wherein said local network management means includes station table means for storing station addresses for indicating the stations that are included within each of said local networks.
28. The system of Claim 27 wherein local network management means includes, means for adding and deleting a station address to said station table means and thereby for adding and deleting, respectively, stations to and from the local networks.
29. The system of Claim 28 wherein local network management means includes, means for adding and deleting a station address to said station table means and thereby for adding and deleting, respectively, one or more stations to and from a plurality of said local networks.
30. The system of Claim 29 wherein local network management means includes each of one or more sta-tions in two or more local networks.
31. The system of Claim 30 wherein one of said one or more stations is a bridge station connecting said one or more stations to another local network.
32. The system of Claim 30 wherein one of said one or more stations is a router station connecting said one or more stations to another local network.
33. The system of Claim 18 wherein each station includes, means for communicating with said local network management means for communicating the ones of the local networks with which the station is associated.
34. The system of Claim 18 wherein each station has a physical connection to a port of said ATM network and wherein said network management means controls the one or more local networks with which the station is associated independently of the physical connect-ion.
CA002144154A 1992-09-14 1993-09-14 Virtual network using asynchronous transfer mode Abandoned CA2144154A1 (en)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US07/944,682 1992-09-14
US07/944,682 US5444702A (en) 1992-09-14 1992-09-14 Virtual network using asynchronous transfer mode

Publications (1)

Publication Number Publication Date
CA2144154A1 true CA2144154A1 (en) 1994-03-31

Family

ID=25481867

Family Applications (1)

Application Number Title Priority Date Filing Date
CA002144154A Abandoned CA2144154A1 (en) 1992-09-14 1993-09-14 Virtual network using asynchronous transfer mode

Country Status (9)

Country Link
US (2) US5444702A (en)
EP (1) EP0746921B1 (en)
JP (1) JP3438891B2 (en)
AT (1) ATE222435T1 (en)
AU (1) AU670126B2 (en)
CA (1) CA2144154A1 (en)
DE (1) DE69332212T2 (en)
DK (1) DK0746921T3 (en)
WO (1) WO1994007316A1 (en)

Families Citing this family (169)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5511168A (en) * 1993-07-01 1996-04-23 Digital Equipment Corporation Virtual circuit manager for multicast messaging
GB2288096B (en) * 1994-03-23 1999-04-28 Roke Manor Research Apparatus and method of processing bandwidth requirements in an ATM switch
US5636216A (en) * 1994-04-08 1997-06-03 Metricom, Inc. Method for translating internet protocol addresses to other distributed network addressing schemes
US6047333A (en) * 1994-05-04 2000-04-04 National Semiconductor Corporation Node adapter including hardware arrangement for filtering broadcast data on network
EP0685950A3 (en) * 1994-06-03 1997-01-29 Philips Patentverwaltung Local asynchronous transfer mode (ATM) network.
JP3340846B2 (en) * 1994-07-05 2002-11-05 富士通株式会社 ATM-LAN, server and ATM address management method
SE504766C2 (en) * 1994-08-18 1997-04-21 Telia Ab Arrangement to provide local area network emulation service over public non-connection ATM network
JP3224963B2 (en) * 1994-08-31 2001-11-05 株式会社東芝 Network connection device and packet transfer method
CA2151180C (en) * 1994-09-14 2003-11-04 Robert Brownhill Method and apparatus for multicast of atm cells
US5930255A (en) * 1995-01-31 1999-07-27 Canon Kabushiki Kaisha Method of setting a relaying path in a communication network
US5583862A (en) * 1995-03-28 1996-12-10 Bay Networks, Inc. Method and apparatus for routing for virtual networks
US5802286A (en) * 1995-05-22 1998-09-01 Bay Networks, Inc. Method and apparatus for configuring a virtual network
US5636371A (en) * 1995-06-07 1997-06-03 Bull Hn Information Systems Inc. Virtual network mechanism to access well known port application programs running on a single host system
EP0836777B1 (en) * 1995-07-05 2004-09-22 Siemens Aktiengesellschaft Arrangement (iwf) for the bidirectional connection of an elan and a cls wide-area network
US7468977B1 (en) * 1995-07-12 2008-12-23 Nortel Networks Limited LAN/ATM switch having local packet switching and an ATM core fabric
US6005864A (en) * 1995-07-14 1999-12-21 3Com Corporation Protocol for optimized multicast services for a connection oriented network providing lan emulation
US5752003A (en) * 1995-07-14 1998-05-12 3 Com Corporation Architecture for managing traffic in a virtual LAN environment
US6041166A (en) 1995-07-14 2000-03-21 3Com Corp. Virtual network architecture for connectionless LAN backbone
JPH11510004A (en) 1995-07-19 1999-08-31 フジツウ ネットワーク コミュニケーションズ,インコーポレイテッド Point-to-multipoint transmission using subqueues
US5805805A (en) * 1995-08-04 1998-09-08 At&T Corp. Symmetric method and apparatus for interconnecting emulated lans
US5657452A (en) * 1995-09-08 1997-08-12 U.S. Robotics Corp. Transparent support of protocol and data compression features for data communication
WO1997010656A1 (en) 1995-09-14 1997-03-20 Fujitsu Network Communications, Inc. Transmitter controlled flow control for buffer allocation in wide area atm networks
JP2891146B2 (en) * 1995-10-23 1999-05-17 日本電気株式会社 Network server
JPH09130421A (en) * 1995-11-02 1997-05-16 Furukawa Electric Co Ltd:The Virtual network controlling method
US5684800A (en) * 1995-11-15 1997-11-04 Cabletron Systems, Inc. Method for establishing restricted broadcast groups in a switched network
JP3511763B2 (en) * 1995-11-17 2004-03-29 株式会社日立製作所 ATM network system and connection admission control method
US6452927B1 (en) 1995-12-29 2002-09-17 Cypress Semiconductor Corporation Method and apparatus for providing a serial interface between an asynchronous transfer mode (ATM) layer and a physical (PHY) layer
US6035105A (en) * 1996-01-02 2000-03-07 Cisco Technology, Inc. Multiple VLAN architecture system
AU1697697A (en) 1996-01-16 1997-08-11 Fujitsu Limited A reliable and flexible multicast mechanism for atm networks
CA2243359A1 (en) * 1996-01-31 1997-08-07 Ipsilon Networks, Inc. Improved method and apparatus for dynamically shifting between routing and switching packets in a transmission network
US5892924A (en) * 1996-01-31 1999-04-06 Ipsilon Networks, Inc. Method and apparatus for dynamically shifting between routing and switching packets in a transmission network
US5898830A (en) 1996-10-17 1999-04-27 Network Engineering Software Firewall providing enhanced network security and user transparency
US5826014A (en) 1996-02-06 1998-10-20 Network Engineering Software Firewall system for protecting network elements connected to a public network
US5850526A (en) * 1996-02-07 1998-12-15 Kingston Technology Co. LAN station for determining the destination LAN station is capable of decompressing by comparing destination address to block of addresses assigned by a LAN manufacturer
US5740375A (en) * 1996-02-15 1998-04-14 Bay Networks, Inc. Forwarding internetwork packets by replacing the destination address
US8117298B1 (en) 1996-02-26 2012-02-14 Graphon Corporation Multi-homed web server
US5812552A (en) * 1996-03-19 1998-09-22 At & T Corp Method and apparatus for dynamically forming multimedia emulated local area networks
US5740171A (en) * 1996-03-28 1998-04-14 Cisco Systems, Inc. Address translation mechanism for a high-performance network switch
US5757796A (en) * 1996-04-26 1998-05-26 Cascade Communications Corp. ATM address translation method and apparatus
US5754790A (en) * 1996-05-01 1998-05-19 3Com Corporation Apparatus and method for selecting improved routing paths in an autonomous system of computer networks
US5787080A (en) * 1996-06-03 1998-07-28 Philips Electronics North America Corporation Method and apparatus for reservation-based wireless-ATM local area network
US5818841A (en) * 1996-06-10 1998-10-06 Mitsubishi Electric Information Technology Center America, Inc. System and process for providing user level multiplexing of two or more application channels to one virtual channel in asynchronous transfer mode network
WO1997048210A1 (en) * 1996-06-14 1997-12-18 Bell Communications Research, Inc. Logical ip address assignment in atm lan
US6400681B1 (en) 1996-06-20 2002-06-04 Cisco Technology, Inc. Method and system for minimizing the connection set up time in high speed packet switching networks
JP3332733B2 (en) * 1996-07-11 2002-10-07 株式会社東芝 Node device and packet transfer method
JP2980032B2 (en) * 1996-08-15 1999-11-22 日本電気株式会社 Connectionless data communication method
US5748905A (en) 1996-08-30 1998-05-05 Fujitsu Network Communications, Inc. Frame classification using classification keys
JP2974280B2 (en) * 1996-09-11 1999-11-10 日本電気通信システム株式会社 Virtual group information management method in network-connected bridge device
US6188689B1 (en) * 1996-10-04 2001-02-13 Kabushiki Kaisha Toshiba Network node and method of frame transfer
US6157647A (en) * 1996-11-06 2000-12-05 3Com Corporation Direct addressing between VLAN subnets
US6073160A (en) * 1996-12-18 2000-06-06 Xerox Corporation Document communications controller
US6041343A (en) * 1996-12-19 2000-03-21 International Business Machines Corp. Method and system for a hybrid peer-server communications structure
US6304546B1 (en) * 1996-12-19 2001-10-16 Cisco Technology, Inc. End-to-end bidirectional keep-alive using virtual circuits
SE511581C2 (en) * 1996-12-20 1999-10-25 Ericsson Telefon Ab L M System and method for ATM connection of a telephone connection
FR2761843B1 (en) * 1997-03-12 2002-05-03 Mannesmann Ag METHOD FOR OPERATING PRIVATE VIRTUAL NETWORKS IN A COMMON NETWORK FOR SWITCHING DATA PACKETS AND DEVICE FOR CARRYING OUT SAID METHOD
US6041057A (en) * 1997-03-24 2000-03-21 Xylan Corporation Self-configuring ATM network
US6757286B1 (en) * 1997-03-24 2004-06-29 Alcatel Self-configuring communication network
US6934249B1 (en) 1997-04-01 2005-08-23 Cisco Technology, Inc. Method and system for minimizing the connection set up time in high speed packet switching networks
US6278705B1 (en) * 1997-04-08 2001-08-21 3Com Corporation Integrated architecture to support a single system image across multiple network access servers
US6026085A (en) 1997-04-08 2000-02-15 3Com Corporation Architecture to support a single system image across multiple network access servers
US6028862A (en) * 1997-05-08 2000-02-22 3Com Corporation Fast path networking
US5959989A (en) * 1997-06-25 1999-09-28 Cisco Technology, Inc. System for efficient multicast distribution in a virtual local area network environment
US6512766B2 (en) 1997-08-22 2003-01-28 Cisco Systems, Inc. Enhanced internet packet routing lookup
US6288739B1 (en) 1997-09-05 2001-09-11 Intelect Systems Corporation Distributed video communications system
US5949783A (en) * 1997-09-08 1999-09-07 3Com Corporation LAN emulation subsystems for supporting multiple virtual LANS
DE19740106A1 (en) * 1997-09-12 1999-03-18 Alsthom Cge Alcatel Method for establishing logical connections in a synchronous digital communication network, network element and management system
US6147993A (en) 1997-10-14 2000-11-14 Cisco Technology, Inc. Method and apparatus for implementing forwarding decision shortcuts at a network switch
US6064674A (en) * 1997-10-22 2000-05-16 International Business Machines Corporation Method and apparatus for hardware forwarding of LAN frames over ATM networks
JP3493309B2 (en) 1997-10-31 2004-02-03 富士通株式会社 Multicast transmission method
US6091732A (en) 1997-11-20 2000-07-18 Cisco Systems, Inc. Method for configuring distributed internet protocol gateways with lan emulation
US6246669B1 (en) 1997-11-28 2001-06-12 Cisco Technology, Inc. Method and system for optimizing connection set-up operations in a high speed digital network
MY123459A (en) * 1998-02-26 2006-05-31 Kenwood Corp Am modulated wave eliminating circuit
US6208649B1 (en) 1998-03-11 2001-03-27 Cisco Technology, Inc. Derived VLAN mapping technique
US6115385A (en) 1998-03-11 2000-09-05 Cisco Technology, Inc. Method and system for subnetting in a switched IP network
US6188691B1 (en) 1998-03-16 2001-02-13 3Com Corporation Multicast domain virtual local area network
US6556584B1 (en) * 1998-04-06 2003-04-29 Motorola, Inc. System and method of communicating non-standardized addresses over a standardized carrier network
US6201792B1 (en) 1998-05-14 2001-03-13 3Com Corporation Backpressure responsive multicast queue
US6223149B1 (en) 1998-05-28 2001-04-24 3Com Corporation Non-distributed LAN emulation server redundancy method
US6269076B1 (en) 1998-05-28 2001-07-31 3Com Corporation Method of resolving split virtual LANs utilizing a network management system
JP3617770B2 (en) * 1998-05-29 2005-02-09 株式会社日立製作所 Network management system and network management method
US6289017B1 (en) 1998-05-29 2001-09-11 3Com Corporation Method of providing redundancy and load sharing among multiple LECs in an asynchronous mode network
US6446122B1 (en) 1998-06-24 2002-09-03 Cisco Technology, Inc. Method and apparatus for communicating quality of service information among computer communication devices
EP1108320A1 (en) * 1998-08-26 2001-06-20 Nortel Networks Limited NON-BROADCAST, MULTIPLE ACCESS INVERSE NEXT HOP RESOLUTION PROTOCOL (InNHRP)
US6785274B2 (en) 1998-10-07 2004-08-31 Cisco Technology, Inc. Efficient network multicast switching apparatus and methods
US6477145B1 (en) 1998-12-30 2002-11-05 At&T Corp. Method and apparatus for using video memory to buffer data packets for presentation to a data network
US6463035B1 (en) 1998-12-30 2002-10-08 At&T Corp Method and apparatus for initiating an upward signaling control channel in a fast packet network
US6480891B1 (en) 1999-01-04 2002-11-12 3Com Corporation Embedded code memory size reduction in asynchronous mode transfer devices
US6556541B1 (en) * 1999-01-11 2003-04-29 Hewlett-Packard Development Company, L.P. MAC address learning and propagation in load balancing switch protocols
US6532237B1 (en) 1999-02-16 2003-03-11 3Com Corporation Apparatus for and method of testing a hierarchical PNNI based ATM network
FI107425B (en) * 1999-03-16 2001-07-31 Nokia Mobile Phones Ltd Method and arrangement for transporting multimedia-related information in a cellular radio network
US6618377B1 (en) * 1999-03-30 2003-09-09 Cisco Technology, Inc. Flexible scheduling of network devices within redundant aggregate configurations
US6839348B2 (en) 1999-04-30 2005-01-04 Cisco Technology, Inc. System and method for distributing multicasts in virtual local area networks
US6553028B1 (en) 1999-04-30 2003-04-22 Cisco Technology, Inc. Method and apparatus for multicast switching using a centralized switching engine
US7778259B1 (en) 1999-05-14 2010-08-17 Dunti Llc Network packet transmission mechanism
US7970929B1 (en) 2002-03-19 2011-06-28 Dunti Llc Apparatus, system, and method for routing data to and from a host that is moved from one location on a communication system to another location on the communication system
US6667967B1 (en) * 1999-05-14 2003-12-23 Omninet Capital, Llc High-speed network of independently linked nodes
US6587462B2 (en) * 2001-02-16 2003-07-01 Dunti Corporation Address mapping mechanism enabling multi-domain addressing in communication networks
US6487171B1 (en) 1999-05-19 2002-11-26 3Com Corporation Crossbar switching matrix with broadcast buffering
US6470022B1 (en) * 1999-05-19 2002-10-22 3Com Corporation Method of distributing network resources fairly between users in an asynchronous transfer mode network
US6580693B1 (en) 1999-05-24 2003-06-17 3Com Corporation Methods and apparatus for detecting leaks in ATM networks
US6539019B1 (en) 1999-05-24 2003-03-25 3Com Corporation Methods and apparatus for automatically connecting a dynamic host configuration protocol (DHCP) client network device to a virtual local area network (VLAN)
US6574232B1 (en) 1999-05-26 2003-06-03 3Com Corporation Crossbar switch utilizing broadcast buffer and associated broadcast buffer management unit
US6614792B1 (en) 1999-05-27 2003-09-02 3Com Corporation Proxy MPC for providing MPOA services to legacy lane clients in an asynchronous transfer mode network
US6775266B1 (en) 1999-07-14 2004-08-10 Telefonaktiebolaget Lm Ericsson Narrowband applications using ATM switching and transport
US6526034B1 (en) 1999-09-21 2003-02-25 Tantivy Communications, Inc. Dual mode subscriber unit for short range, high rate and long range, lower rate data communications
US6654347B1 (en) * 1999-10-22 2003-11-25 Dell Usa L.P. Site-to-site dynamic virtual local area network
US6683866B1 (en) * 1999-10-29 2004-01-27 Ensemble Communications Inc. Method and apparatus for data transportation and synchronization between MAC and physical layers in a wireless communication system
US6678241B1 (en) 1999-11-30 2004-01-13 Cisc Technology, Inc. Fast convergence with topology switching
US6862285B1 (en) * 1999-12-13 2005-03-01 Microsoft Corp. Method and system for communicating with a virtual circuit network
US6665730B1 (en) * 1999-12-16 2003-12-16 At&T Corp. Method and apparatus for transaction routing in a connection-oriented packet network using a non-fault-tolerant directory server
US6931003B2 (en) * 2000-02-09 2005-08-16 Bookline Flolmstead Llc Packet prioritization protocol for a large-scale, high speed computer network
US7016351B1 (en) 2000-02-29 2006-03-21 Cisco Technology, Inc. Small group multicast in a computer network
FI113606B (en) * 2000-05-03 2004-05-14 Nokia Corp Procedure for conveying messages, communication systems and terminal
US7065079B1 (en) 2000-05-04 2006-06-20 Cisco Technology, Inc. VC sharing for multicast in a computer network
FI20001312A (en) * 2000-05-31 2001-12-01 Nokia Networks Oy Formation of a telecommunications network
US7496095B1 (en) * 2000-06-22 2009-02-24 Intel Corporation Local area network emulation over a channel based network
FI20001509A (en) 2000-06-26 2001-12-27 Nokia Networks Oy Packet data transmission system and network element
US7092390B2 (en) * 2000-09-07 2006-08-15 Sbc Technology Resources, Inc. Internal substitution bi-level addressing for compatible public networks
JP2002101103A (en) * 2000-09-20 2002-04-05 Nec Saitama Ltd Base station modulator and demodulator, and atm cell transmission/reception method
US7389359B2 (en) 2001-10-19 2008-06-17 Foundry Networks, Inc. Method and system for intelligently forwarding multicast packets
US7647422B2 (en) 2001-11-06 2010-01-12 Enterasys Networks, Inc. VPN failure recovery
US8045565B1 (en) 2001-11-20 2011-10-25 Brookline Flolmstead Llc Method and apparatus for an environmentally hardened ethernet network system
US7170897B2 (en) * 2001-12-06 2007-01-30 Alcatel Canada Inc. Method and apparatus for implementing point-to-multipoint communications over a connection- based data communication network
US7113512B1 (en) * 2001-12-12 2006-09-26 At&T Corp. Ethernet-to-ATM interworking technique
MXPA04005816A (en) * 2001-12-15 2004-09-10 Thomson Licensing Sa Quality of service setup on a time reservation basis.
US20050226172A1 (en) * 2001-12-15 2005-10-13 Richardson John W Video conference call set up
JP2005539409A (en) * 2002-03-01 2005-12-22 エンテラシス ネットワークス インコーポレイテッド Position recognition data network
US7301951B2 (en) * 2002-07-31 2007-11-27 At&T Knowledge Ventures, L.P. Resource reservation protocol based guaranteed quality of service internet protocol connections over a switched network
US7272145B2 (en) * 2002-07-31 2007-09-18 At&T Knowledge Ventures, L.P. Resource reservation protocol based guaranteed quality of service internet protocol connections over a switched network through proxy signaling
US7298750B2 (en) * 2002-07-31 2007-11-20 At&T Knowledge Ventures, L.P. Enhancement of resource reservation protocol enabling short-cut internet protocol connections over a switched network
US7065092B2 (en) * 2002-07-31 2006-06-20 Sbc Properties, L.P. Resource reservation protocol based guaranteed quality of service internet protocol (IP) connections over a switched network using newly assigned IP addresses
US9451422B2 (en) * 2003-03-17 2016-09-20 Nokia Technologies Oy Method, system and network device for routing a message to a temporarily unavailable network user
KR100703380B1 (en) * 2003-05-14 2007-04-03 삼성전자주식회사 Apparatus and method for transmitting/receiving control information for multimedia broadcast/multicast service
US7447203B2 (en) 2003-07-29 2008-11-04 At&T Intellectual Property I, L.P. Broadband access for virtual private networks
US7739394B2 (en) * 2003-07-29 2010-06-15 At&T Intellectual Property I, L.P. Bi-level addressing for internet protocol broadband access
KR20050018050A (en) * 2003-08-12 2005-02-23 삼성전자주식회사 Method for setting broadcasting service header information in a mobile communication system
US7065144B2 (en) * 2003-08-27 2006-06-20 Qualcomm Incorporated Frequency-independent spatial processing for wideband MISO and MIMO systems
JP4196801B2 (en) * 2003-10-01 2008-12-17 株式会社日立製作所 Radio system and mobile station
US8233462B2 (en) * 2003-10-15 2012-07-31 Qualcomm Incorporated High speed media access control and direct link protocol
US8284752B2 (en) * 2003-10-15 2012-10-09 Qualcomm Incorporated Method, apparatus, and system for medium access control
TWI383302B (en) * 2003-10-15 2013-01-21 Qualcomm Inc Wireless lan protocol stack
US8472473B2 (en) 2003-10-15 2013-06-25 Qualcomm Incorporated Wireless LAN protocol stack
US9226308B2 (en) 2003-10-15 2015-12-29 Qualcomm Incorporated Method, apparatus, and system for medium access control
US8842657B2 (en) 2003-10-15 2014-09-23 Qualcomm Incorporated High speed media access control with legacy system interoperability
US8483105B2 (en) 2003-10-15 2013-07-09 Qualcomm Incorporated High speed media access control
US8462817B2 (en) 2003-10-15 2013-06-11 Qualcomm Incorporated Method, apparatus, and system for multiplexing protocol data units
US7102995B2 (en) * 2003-12-05 2006-09-05 Rumi Sheryar Gonda Supporting SDH/SONET APS bridge selector functionality for ethernet
US7818018B2 (en) * 2004-01-29 2010-10-19 Qualcomm Incorporated Distributed hierarchical scheduling in an AD hoc network
US8903440B2 (en) 2004-01-29 2014-12-02 Qualcomm Incorporated Distributed hierarchical scheduling in an ad hoc network
US7580403B2 (en) 2004-02-26 2009-08-25 Enterasys Networks, Inc. Status transmission system and method
US8315271B2 (en) 2004-03-26 2012-11-20 Qualcomm Incorporated Method and apparatus for an ad-hoc wireless communications system
US7362710B2 (en) * 2004-05-03 2008-04-22 Lucent Technologies Inc. Organization and maintenance loopback cell processing in ATM networks
US7564814B2 (en) 2004-05-07 2009-07-21 Qualcomm, Incorporated Transmission mode and rate selection for a wireless communication system
US8401018B2 (en) 2004-06-02 2013-03-19 Qualcomm Incorporated Method and apparatus for scheduling in a wireless network
US8458453B1 (en) 2004-06-11 2013-06-04 Dunti Llc Method and apparatus for securing communication over public network
US7945945B2 (en) * 2004-08-06 2011-05-17 Enterasys Networks, Inc. System and method for address block enhanced dynamic network policy management
US7882412B2 (en) 2004-10-05 2011-02-01 Sanjiv Nanda Enhanced block acknowledgement
US7347628B2 (en) 2004-11-08 2008-03-25 Enterasys Networks, Inc. Optical interface identification system
CN100442706C (en) * 2005-04-19 2008-12-10 华为技术有限公司 Method for making maintaining node labels to match with media visiting controlled addresses
US8086232B2 (en) 2005-06-28 2011-12-27 Enterasys Networks, Inc. Time synchronized wireless method and operations
US8600336B2 (en) 2005-09-12 2013-12-03 Qualcomm Incorporated Scheduling with reverse direction grant in wireless communication systems
US7969966B2 (en) * 2005-12-19 2011-06-28 Alcatel Lucent System and method for port mapping in a communications network switch
US20070171825A1 (en) * 2006-01-20 2007-07-26 Anagran, Inc. System, method, and computer program product for IP flow routing
US8547843B2 (en) * 2006-01-20 2013-10-01 Saisei Networks Pte Ltd System, method, and computer program product for controlling output port utilization
US8683572B1 (en) 2008-01-24 2014-03-25 Dunti Llc Method and apparatus for providing continuous user verification in a packet-based network
US8942166B2 (en) * 2010-02-12 2015-01-27 Google Technology Holdings LLC Method for providing a contention based uplink channel
US8441965B2 (en) * 2010-08-05 2013-05-14 Apple Inc. Methods and apparatus for reducing data transmission overhead
JP5601193B2 (en) * 2010-12-22 2014-10-08 富士通株式会社 Network relay system, network relay device, congestion state notification method, and program
KR101986099B1 (en) * 2018-01-05 2019-06-05 (주)에프씨아이 Method and Apparatus for Filtering for Reducing Wake-UP Frequency

Family Cites Families (15)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5144622A (en) 1988-02-15 1992-09-01 Hitachi, Ltd. Network system
US5101404A (en) * 1988-08-26 1992-03-31 Hitachi, Ltd. Signalling apparatus for use in an ATM switching system
JP2860661B2 (en) * 1989-03-14 1999-02-24 国際電信電話 株式会社 ATM switch
JP2964151B2 (en) * 1989-07-03 1999-10-18 富士通株式会社 Communication control method
JP2531275B2 (en) * 1989-09-29 1996-09-04 日本電気株式会社 ATM cell transfer method
DE4008078A1 (en) * 1990-03-14 1991-09-19 Standard Elektrik Lorenz Ag COPYABLE ATM SWITCH
US5136580A (en) * 1990-05-16 1992-08-04 Microcom Systems, Inc. Apparatus and method for learning and filtering destination and source addresses in a local area network system
US5140585A (en) * 1990-07-19 1992-08-18 Kabushiki Kaisha Toshiba Star local-area network system
JP2878805B2 (en) * 1990-08-20 1999-04-05 株式会社東芝 ATM switch
JPH04107029A (en) * 1990-08-27 1992-04-08 Mitsubishi Electric Corp System for connection between local area networks
JPH04138739A (en) * 1990-09-28 1992-05-13 Toshiba Corp Communication control system using asynchronous transmission mode network
AU647267B2 (en) * 1991-05-07 1994-03-17 Fujitsu Limited Switching node in label multiplexing type switching network
US5420858A (en) * 1993-05-05 1995-05-30 Synoptics Communications, Inc. Method and apparatus for communications from a non-ATM communication medium to an ATM communication medium
JP2546505B2 (en) * 1993-06-23 1996-10-23 日本電気株式会社 Address learning device in CLAD
US5408469A (en) * 1993-07-22 1995-04-18 Synoptics Communications, Inc. Routing device utilizing an ATM switch as a multi-channel backplane in a communication network

Also Published As

Publication number Publication date
EP0746921A1 (en) 1996-12-11
AU4921593A (en) 1994-04-12
JP3438891B2 (en) 2003-08-18
EP0746921A4 (en) 1998-12-09
ATE222435T1 (en) 2002-08-15
WO1994007316A1 (en) 1994-03-31
EP0746921B1 (en) 2002-08-14
DK0746921T3 (en) 2002-11-11
AU670126B2 (en) 1996-07-04
DE69332212D1 (en) 2002-09-19
JPH08501424A (en) 1996-02-13
US5633869A (en) 1997-05-27
DE69332212T2 (en) 2002-12-12
US5444702A (en) 1995-08-22

Similar Documents

Publication Publication Date Title
CA2144154A1 (en) Virtual network using asynchronous transfer mode
US5280481A (en) Local area network transmission emulator
CA2217090C (en) System and method for performing switching in multipoint-to-multipoint multicasting
US6385204B1 (en) Network architecture and call processing system
Fraser et al. Xunet 2: A nationwide testbed in high-speed networking
JP2962276B2 (en) Session management system and connection management system in ATM connectionless communication network
US6570878B2 (en) Network and method for ATM network operations
GB2254529A (en) Connectionless switching for an atm or dqdb switch
EP0776563B1 (en) Device for broadband data service transmission in telecommunication system
EP0903046B1 (en) Improvements in, or relating to, atm transmission by radio
Omundsen et al. A pipelined, multiprocessor architecture for a connectionless server for broadband ISDN
Hidell Supporting the Internet Protocols in a High Performance Real-Time Network
Olsen et al. Design and implementation of a fast virtual channel establishment method for ATM networks
Tantawy Bridging issues in DQDB subnetworks
Camarda et al. A router for the interconnection of Ethernet local area networks via an ATM network
Gavras et al. Bergate-A system for interconnecting local area networks via broadband ISDN
Ray Asynchronous Transfer Mode (ATM) Technology and Applications
Angelopoulos et al. Connection oriented high speed MANs and LANs: a requirement for B-ISDN evolution
Muth Logical Network Modelling
Drucker et al. An X. 25 Interface to the PLRS/JTIDS Network
CA2310597A1 (en) Method for relaying ip application frames in an atm switch with distributed network architecture

Legal Events

Date Code Title Description
EEER Examination request
FZDE Discontinued