Trailing-Edge
-
PDP-10 Archives
-
BB-X116A-BB_1984
-
router.mac
There are 25 other files named router.mac in the archive. Click here to see a list.
;DNET:ROUTER.MAC[10,36,MON,NEW], 30-Oct-1983 03:16:14, Edit by TARL
;MCO 11027(a) - Teach RTEEXN to pick up adjacent node in circuit block
;DNET:ROUTER.MAC[10,36,MON,NEW], 30-Oct-1983 02:26:14, Edit by TARL
;MCO 11027 - Teach RTNEVT how to find router header on output messages.
;DNET:ROUTER.MAC[10,36,MON,NEW], 29-Oct-1983 05:33:42, Edit by TARL
;MCO 11025 - Add code to talk with non-routing phase III nodes.
;DNET:ROUTER.MAC[10,36,MON,NEW], 23-Oct-1983 17:14:35, Edit by TARL
;MCO 11016 - ROUBCD's caused by RTRRCR getting called at interrupt level,
; by RTIDWN and friends. SETOM RTRRCF instead
;DNET:ROUTER.MAC[10,36,MON,NEW], 05-Oct-1983 05:26:52, Edit by TARL
;MCO 10994 - Fix loop node stuff
;TITLE ROUTER - Routing Layer Service for DECnet-36
SUBTTL V. Brownell/Tarl/AJR
SEARCH D36PAR,MACSYM
SALL
ENTRY RTRINI
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
IFN FTOPS10,<
.CPYRT<
COPYRIGHT (C) 1984 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
>
> ;END IFN FTOPS10
IFN FTOPS20,<
SEARCH PROLOG,PROKL
TTITLE ROUTER,,< - Routing Layer Service for DECnet-36>
>
IFN FTOPS10,<
SEARCH F,S
TITLE ROUTER - Routing Layer Service for DECnet-36
>;END OF IFN FTOPS10
D36SYM ;SET UP D36 SPECIFIC PARAMETERS
$RELOC
$HIGH ;RELOC TO HIGHSEG (RSCOD PSECT ON TOPS-20)
SUBTTL Table of Contents
; Table of Contents for ROUTER
;
;
; Section Page
; 1. Table of Contents. . . . . . . . . . . . . . . . . . . 2
; 2. Definitions
; 2.1. External References . . . . . . . . . . . . . 3
; 2.2. Accumulators. . . . . . . . . . . . . . . . . 5
; 2.3. Macros. . . . . . . . . . . . . . . . . . . . 6
; 2.4. Packet Route Header . . . . . . . . . . . . . 7
; 2.5. Router Control Message. . . . . . . . . . . . 8
; 2.6. Phase II Messages . . . . . . . . . . . . . . 9
; 2.7. Routing Vectors . . . . . . . . . . . . . . . 10
; 2.8. Miscellaneous . . . . . . . . . . . . . . . . 11
; 3. RTRINI - Initialize Router User. . . . . . . . . . . . 12
; 4. RTRON - Turn Router (and DECnet) On. . . . . . . . . . 13
; 5. RTROFF - Turn Router (and DECnet) Off. . . . . . . . . 14
; 6. RTRSEC - Once a second processing for Router . . . . . 15
; 7. RTRJIF - Once a jiffy processing for Router. . . . . . 16
; 8. RTRXMT - NSP's Entry in Router . . . . . . . . . . . . 18
; 9. RTRFWD - Perform Routing of Message. . . . . . . . . . 19
; 10. RTR2RM - Send Message to Remote Node . . . . . . . . . 22
; 11. R2NODN - Return Output Done to NSP . . . . . . . . . . 25
; 12. R2NRTN - Return Message to NSP . . . . . . . . . . . . 26
; 13. R2NRCV - Pass Recieved Message to NSP. . . . . . . . . 27
; 14. R2KINI - Initialize a Kontroller's Circuit . . . . . . 28
; 15. R2KHLT - Halt the Kontroller's Circuit . . . . . . . . 29
; 16. CALKON - Call the Kontroller . . . . . . . . . . . . . 30
; 17. CALQOB - Call CALKON for queued output.. . . . . . . . 31
; 18. RTRRCR - Recompute Routing . . . . . . . . . . . . . . 32
; 19. RTRSRM - Send routing messages if needed . . . . . . . 37
; 20. RTRTMR - Routine to perform timer functions. . . . . . 40
; 21. Circuit Interface
; 21.1. RTRDSP - Circuit Drivers Entry. . . . . . . . 43
; 21.2. RTIOPN - Open a new circuit . . . . . . . . . 45
; 21.3. RTICLS - Close a Circuit. . . . . . . . . . . 46
; 21.4. RTIPRU - Process Protocol Up. . . . . . . . . 47
; 21.5. RTIDWN - Process Protocol Down. . . . . . . . 49
; 21.6. RTIMMR - Process Maintainence Message . . . . 50
; 21.7. RTISMR - Process Start Message. . . . . . . . 51
; 21.8. RTIBRQ - Process the Buffer Request . . . . . 52
; 21.9. RTIOTC - Process Output Complete. . . . . . . 53
; 21.10. RTIOTI - Process Output Incomplete. . . . . . 54
; 21.11. RTIINC - Process Input Complete . . . . . . . 55
; 22. Control Message Processors
; 22.1. RTCINI - Init Messages. . . . . . . . . . . . 58
; 22.2. RTCVER - Verification Messages. . . . . . . . 61
; 22.3. RTCRTE - Routing Messages . . . . . . . . . . 62
; 22.4. RTCTST - Test or Hello Messages . . . . . . . 64
; 23. RTRHDP - Parse a Input Router Message Header . . . . . 65
; 24. RTRPH2 - Handle Phase II Messages. . . . . . . . . . . 67
; 25. Network Management Interface
; 25.1. RTNSNT - Set node type. . . . . . . . . . . . 75
; 25.2. RTNRNT - Read node's type . . . . . . . . . . 76
; 25.3. RTNSLS - Set Circuit State. . . . . . . . . . 77
; 25.4. RTNGLS - Circuit state routine. . . . . . . . 79
; 25.5. RTNGLB - Circuit substate . . . . . . . . . . 80
; 25.6. RTNLID - Give the line id . . . . . . . . . . 81
; 25.7. RTRNMX - Do circuit functions . . . . . . . . 82
; 25.8. Router Event Types. . . . . . . . . . . . . . 83
; 25.9. Reason Definitions. . . . . . . . . . . . . . 85
; 25.10. RTNEVT - Event Reporter . . . . . . . . . . . 86
; 25.11. Event Parameter Processors. . . . . . . . . . 87
; 25.12. Event Processor Subroutines . . . . . . . . . 89
; 25.13. Miscellaneous Event Processors. . . . . . . . 90
; 26. Miscellaneous Routines
; 26.1. RTRZCB - Zap Circuit Block. . . . . . . . . . 92
; 26.2. RTRMCB - Make a Circuit Block . . . . . . . . 93
; 26.3. RTRGCB - Get Circuit Block Pointer. . . . . . 94
; 26.4. CPYMSG - Copy all MSDs together . . . . . . . 95
; 26.5. FREMSG - Toss a Message . . . . . . . . . . . 96
; 26.6. CKSNRM - Normalize Checksum . . . . . . . . . 97
; 27. Local Router Storage . . . . . . . . . . . . . . . . . 98
; 28. End of ROUTER. . . . . . . . . . . . . . . . . . . . . 99
SUBTTL Definitions -- External References
;These are the external references to the D36COM library of routines.
EXT DNGINI ;INITIALIZE FOR INPUT (DGXYBY)
EXT DNPINI ;INITIALIZE FOR OUTPUT (DPXYBY)
EXT DNP1BY ;PUT ONE BYTE IN MESSAGE
EXT DNP2BY ;PUT TWO BYTES IN MESSAGE
EXT DNPEBY ;PUT AN EXTENSIBLE BYTE IN MESSAGE
EXT DNG1BY ;GET ONE BYTE FROM MESSAGE
EXT DNG2BY ;GET TWO BYTES FROM MESSAGE
EXT DNGEBY ;GET EXTENSIBLE BYTE FROM MESSAGE
EXT DNGMSG ;GET DECNET-36 MESSAGE BLOCK
EXT DNFMSG ;FREE MESSAGE BLOCK
EXT DNMINI ;RE-USE MESSAGE BLOCK
EXT DNGEBF ;ADD EMERGENCY BUFFER TO FREE LIST
EXT DNGEMS ;GET EMERGENCY MESSAGE BLOCK
EXT DNNMSG ;GET NUMBER OF BUFFERS AVAILABLE TO ROUTER
EXT DNLENG ;GET THE MESSAGE LENGTH
EXT DNSLNG ;FIND THE SEGMENT LENGTH
EXT DNGWDS ;GET SOME WORDS
EXT DNGWDZ ;GET SOME ZEROED WORDS
EXT DNFWDS ;FREE SOME WORDS
EXT DNSWDS ;SMEAR SOME WORDS
EXT DNBKBY ;GO BACKWARDS SOME BYTES
EXT DNSKBY ;SKIP SOME BYTES
EXT DNRPOS ;RETURN POSTION IN MESSAGE
EXT DNGPOS ;GO TO POSITION IN MESSAGE
EXT DNLMSS ;LINK MESSAGE SEGMENT INTO MESSAGE BLOCK
EXT DNCPMS ;COPY MESSAGE BLOCKS
EXT DNGTIM ;RETURN CURRENT UPTIME (IN MS)
;These are external data locations.
EXT DCNSTA ;THE STATE VARIABLE OF DECNET
EXT TIMBAS ;UNITS TO CONVERT FROM DNGTIM TO SECONDS.
;This is the reference to LLINKS.
EXT NSPRTR ;THE ONE AND ONLY
;We need to know our node name for Phase II NI messages.
EXT SCTA2N ;PERFORM TRANSLATION FROM ADDRESS TO NODE NAME
;These are some default parameters
EXT %RTMXN ;DEFAULT MAXIMUM NODE NUMBER
EXT %RTMXC ;DEFAULT MAXIMUM CIRCUIT COST
EXT %RTMXH ;DEFAULT MAXIMUM HOPS
EXT %RTMXV ;MAXIMUM VISITS COUNT
IFN FTOPS10,EXT %RTADR ;DEFAULT LOCAL ADDRESS
EXT %RTTM1 ;LONG TIMER
EXT %RTTM3 ;HELLO MESSAGE TIMER
EXT %RTTM4 ;NODE LISTENER TIMEOUT VALUE
EXT %RTITM ;TI TIMER
EXT %RTCST ;DEFAULT CIRCUIT COST
EXT %RTBSZ ;DEFAULT BLOCK SIZE
EXT %RTVER ;ROUTER VERSION NUMBER
EXT %RTECO ;EDIT LEVEL
EXT %RTCUS ;CUSTOMER EDIT LEVEL
;Other external references
EXT NMXEVT ;REPORT AN EVENT TO NMX
EXT NTEIPV ;TELL NETWORK MANAGEMENT THAT BAD VALUE
EXT KONDSP ;KONTROLLER DISPATCH
EXT RTN ;NON-SKIP RETURN
EXT RSKP ;SKIP RETURN
;Interlock management
IFN FTOPS10,<
EXT .CPCPN ;CURRENT CPU NUMBER
EXT .CPSK0 ;SKIP IF CURRENT CPU IS BOOT CPU
>
SUBTTL Definitions -- Accumulators
;These are some local AC defintions for Router-36.
RC=FREE1 ;RC USUALLY POINTS TO THE CIRCUIT BLOCK
PURGE FREE1 ;LOSE THIS SYMBOL
SUBTTL Definitions -- Macros
;Event Logging Macro
DEFINE EVENT(TYPE,TEXT,MSGBLK),<
CALL [
IFN FTTRACE,<
ETRACE RTR,<RTR Event: 'TEXT>
>
MOVX T1,TYPE ;;PUT EVENT TYPE IN T1
IFNB <MSGBLK>,MOVE T4,'MSGBLK ;;IF HE GAVE MB POINTER, GIVE IT
IFB <MSGBLK>, SETZ T4, ;;IF NOT, GIVE RTNEVT A ZERO
CALLRET RTNEVT] ;;CALL THE EVENT PROCESSOR AND RETURN
>
SUBTTL Definitions -- Packet Route Header
;The first byte of the packet route header is defined in the Router
;section of the message block structure. This is purely for convience
;sake. The whole byte is called RMFST and each bit is defined within
;this field.
;The only other field that has to be defined (other than the source and
;destination address) is the FORWARD field which simply consists of the
;VISITS field.
BEGSTR FW ;FORWARD BYTE
FIELDM VST,77 ; VISITS COUNT
ENDSTR
SUBTTL Definitions -- Router Control Message
;The following are field definitions for the Router Control messages.
;Control message all begin with the field CTLFLG, which specifies the type
;of control message.
BEGSTR CM ;CTLFLG
FIELDM TYP,7_1 ; TYPE OF MESSAGE
FIELDM CTL,1
ENDSTR
;These are the various types of router control messages (in CMTYP).
XP XCT.TI,0 ;ROUTER INIT
XP XCT.TV,1 ;ROUTER VERIFICATION
XP XCT.TT,2 ;ROUTER TEST
XP XCT.RM,3 ;ROUTER ROUTING MESSAGE
;Routing control messages consist of a RTGINFO entry for every node in
;the network, followed by a two byte checksum.
BEGSTR RG ;RTGINFO
FIELDM HOP,37_^D10 ; HOPS
FIELDM CST,1777 ; COST
ENDSTR
;Transport Initialization control messages start with field TIINFO which
;contains the node type and verification required flags.
BEGSTR TI ;TIINFO
FIELDM RSV,37_3 ; RESERVED
FIELDM VER,1_2 ; VERIFY FLAG
FIELDM NTY,3 ; NODE TYPE
ENDSTR
XP TI.MXL,^D10 ;MAX LENGTH OF TRANSPORT INIT MSG
;These are the possible types of nodes that can be at the other end
;of a circuit (in FIELD TINTY).
XP RNT.XX,0 ;RESERVED
XP RNT.X1,1 ;RESERVED FOR PHASE IV
XP RNT.RT,2 ;ROUTING
XP RNT.NR,3 ;NON-ROUTING
;Router hello message has NO.HEL bytes of the byte HEL.LO.
XP NO.HEL,^D10 ;NUMBER OF TEST BYTES
XP HEL.LO,^O252 ;CONSTANT FOR HELLO AND TEST MESSAGES
SUBTTL Definitions -- Phase II Messages
;The First Byte of the "router" message may have the "evolution bit"
;turned on. If it is turned on, the first byte is actually either the
;RTFLG byte of a Phase II RTHDR (routing header) or the MSGFLG field of
;a Phase II NSP message.
;The MSGFLG field of Phase II messages.
BEGSTR MF ;MSGFLG
FIELDM TYP,3_2 ; TYPE MESSAGE
FIELDM SUB,7_4 ; SUBTYPE OF MESSAGE
ENDSTR
;Types of Phase II messages (field MFTYP).
XP MFT.DA,0 ;DATA MESSAGE
XP MFT.AK,1 ;ACKNOWLEDGE
XP MFT.CT,2 ;CONTROL MESSAGE
XP MFT.RS,3 ;RESERVED
;The only SUBTYPE we are concered about is the STARTUP type.
XP MFC.ST,5 ;STARTUP CONTROL MESSAGE
;STARTTYPE field.
XP STT.NI,1 ;NODE INITIALIZATION
XP STT.NV,2 ;NODE VERIFICATION
;These are the lengths of the various START messages.
XP NI.MXL,^D56 ;NODE INITIALIZATION
XP NV.MXL,^D11 ;NODE VERIFICATION
;Node Initialization Message fields.
;REQUESTS field
BEGSTR RE
FIELDM RIN,3_1 ;REQUEST INTERCEPT TYPE
;**MUST BE ZERO (NO INTERCEPT)**
FIELDM VER,1 ;VERIFICATION REQUIRED
ENDSTR
SUBTTL Definitions -- Routing Vectors
;These are the definitions for each entry in both the scratch and the
;normal routing vectors. The vectors consist of one entry for each
;possible node in the network. Non-existant (un-reachable) nodes are
;set to the maximum node cost and hops.
BEGSTR RN
FIELD FLG,3 ;FLAGS
BIT RCH ;IF SET, NODE IS REACHABLE
BIT LCL ;NODE IS LOCL NSP USER
FIELD HOP,5 ;MIN HOPS
FIELD CST,10 ;MIN COST
ENDSTR
;Define right justified symbols for max-cost and max-hops.
XP RN%CST,MASK.(WID(RNCST),^D35) ;MAX COST
XP RN%HOP,MASK.(WID(RNHOP),^D35) ;MAX HOPS
SUBTTL Definitions -- Miscellaneous
;Here is the definitions for the node type vector. This is used presently,
;only to see if a node is defined as a "Phase II" node.
XP NT.WID,2 ;WIDTH OF EACH NODE'S ENTRY IN VECTOR
XP NTV.P2,1 ;NODE IS PHASE II+ OR PHASE II
XP NTV.P3,0 ;NODE IS A PHASE III NODE
SUBTTL RTRINI - Initialize Router User
;RTRINI - Set up a router user
;
; Call:
; with nothing
;
; Return:
; RET ;ON RESOURCE FAILURE
; RETSKP ;ON SUCCESS
;
; Uses: T1-T3
;
;This routine gets called at system initialization. It sets up the memory
;for the routing vectors and the node type vector. Must be called before
;DECnet is turned on.
RTRINI::TRACE RTR,<Initializing Router>
;Here to allocate the "normal" and "scratch" routing vectors.
MOVE T1,RTRMXN ;GET THE MAXIMUM NODE NUMBER
ADDI T1,1 ;ONE EXTRA FOR EASY INDEXING
ASH T1,1 ;MAKE IT TWICE AS LONG (HALF FOR RCH VECTOR
; HALF FOR OUTPUT CIRCUIT VECTOR)
CALL DNGWDZ ;GET THAT MANY WORDS
RET ;COULD NOT INITIALIZE
MOVEM T1,RTRNRV ;SAVE POINTER TO NORMAL ROUTING VECTOR
MOVE T2,RTRMXN ;GET OUR CURRENT MAX-NODES
ADDI T2,1 ;START THE RTRNOV AT ONE ALSO
MOVEM T2,RTROFS ;SAVE AS OFFSET FROM START OF NRV AND SRV
; NOTE THAT MXN CANNOT GET LARGER!
ADD T1,T2 ;CALCULATE START OF NORMAL OUTPUT VECTOR
MOVEM T1,RTRNOV ;SAVE IT
MOVE T2,RTRNRV ;PREPARE TO CALC END OF SMEAR
ADD T2,RTRMXN ;ADD NUMBER OF ENTRIES TO SPRAY
MOVE T1,RTRNRV ;POINT TO THE HEAD OF THE NORMAL VECTOR
ADDI T1,1 ;NODE NUMBERS START AT ONE
MOVX T3,RNHOP!RNCST ;SMEAR WITH MAXIMUM COST AND HOPS
CALL DNSWDS ;SPRAY THE BLOCK WITH MAXS
MOVE T1,RTRMXN ;GET MAXIMUM NODE NUMBER
ADDI T1,1 ;ONE MORE
ASH T1,1 ;MULT BY TWO (ONE FOR SRV, ONE FOR SOV)
CALL DNGWDZ ;GET THE WORDS FOR SCRATCH VECTOR
RET ;OOPS, GIVE BAD RETURN
MOVEM T1,RTRSRV ;SAVE THE SCRATCH ROUTING VECTOR POINTER
ADD T1,RTROFS ;CALCULATE START OF SOV
MOVEM T1,RTRSOV ;SAVE SOV FOR LATER USERS
;Set up the node type vector.
MOVE T1,RTRMXN ;GET MAX-NODES
IMULI T1,NT.WID ;EACH ONE IS THIS WIDE
IDIVI T1,^D36 ;HOW MANY WORDS
ADDI T1,1 ;ONE MORE FOR REMAINDER
CALL DNGWDZ ;GET THAT MANY WORDS
RET ;OOPS, WE'VE GOT A PROBLEM
MOVEM T1,RTRNTV ;SAVE THE POINTER TO THE VECTOR
RETSKP ;RETURN NICELY
SUBTTL RTRON - Turn Router (and DECnet) On
;RTRON - Turn Router (and DECnet) On
;
; Call:
; With nothing special
;
; Return:
; RET ;ON FAILURE (DECNET IS ALREADY ON, NO
; ;LOCAL NODE NUMBER DEFINED, ETC.)
; RETSKP ;WITH DECNET TURNED ON
;
; Uses: T1-T4
;
;Note that RTRINI must be called to set up the routing vectors for
;Router before DECnet is turned on.
RTRON:: SAVEAC RC
SKIPN DCNSTA ;IS DECNET TURNED ON?
SKIPN T1,RTRADR ;AND DO WE HAVE AN ADDRESS FOR TRANSPORT?
RET ;NO, CANNOT TURN DECNET ON YET
ADD T1,RTRNRV ;FIND THE ENTRY IN THE NORMAL REACH VECTOR
D36OFF ;TURN ON INTERLOCK
SETONE <RNLCL,RNRCH>,(T1) ;MAKE IT LOCAL AND REACHABLE
SETZRO <RNCST,RNHOP>,(T1) ;ZERO THE HOPS AND COST FOR THIS NODE
XMOVEI T2,NSPRTR ;GET NSP'S ENTRY VECTOR
ADD T1,RTROFS ;POINT TO OUTPUT-CIRCUIT VECTOR ENTRY
MOVEM T2,(T1) ;SAVE THE ENTRY VECTOR
D36ON ;TURN OFF INTERLOCK
;And turn DECnet on!
MOVX T1,DS.ON ;GET THE ON STATE
MOVEM T1,DCNSTA ;SET IT
;Now go through all the circuits, initializing each one.
SKIPN RC,RTRCBQ ;PICK UP FIRST CIRCUIT BLOCK
RETSKP ;NONE THERE, RETURN SUCCESS
RTRON1: CALL R2KINI ;INITIALIZE THIS CIRCUIT
LOAD RC,RCNXT,(RC) ;STEP THROUGH TO NEXT ONE
JUMPN RC,RTRON1 ; AND INITIALIZE IF ANY MORE
RETSKP ;NO MORE, JUST RETURN SUCCESS
SUBTTL RTROFF - Turn Router (and DECnet) Off
;RTROFF - Turn Router (and DECnet) Off
;
; Call:
; With nothing special
;
; Return:
; RETSKP ;ALWAYS
;
; Uses: T1-T4
RTROFF::SAVEAC RC
;Now go through all the circuits, halting each one.
SKIPN RC,RTRCBQ ;PICK UP FIRST CIRCUIT BLOCK
JRST RTROF2 ;NONE THERE, RETURN SUCCESS
RTROF1: CALL R2KHLT ;HALT THIS CIRCUIT
LOAD RC,RCNXT,(RC) ;STEP THROUGH TO NEXT ONE
JUMPN RC,RTROF1 ; AND HALT IF ANY MORE
RTROF2: MOVX T1,DS.OFF ;SET THE STATE OF DECNET
MOVEM T1,DCNSTA ; TO "OFF"
RETSKP ;NO MORE, JUST RETURN SUCCESS
SUBTTL RTRSEC - Once a second processing for Router
;RTRSEC - Once a second processing
;
; Call:
; With nothing
;
;Return:
; RET ;ALWAYS
;
; Uses: T1
;
;This is the clock level routine for Router. Once a second this
;routine gets executed. If we are running TOPS-10 SMP, we must make
;sure that this is run on the BOOT CPU. The routine simply calls RTRRCR
;(to recompute the routing) if needed and calls RTRSRM to see if
;routing messages need to be sent out on any or all circuits. Next, we
;call the hello processor to check hello and listener timers for each
;circuit. Finally, it checks the resend queue, and if there are any
;messages on it, it forwards them.
RTRSEC::
IFN FTOPS20,< ;ON TOPS-20 RTRSEC IS CALLED EVERY 100 MS
MOVEI T1,^D1000 ;GET MILLISECONDS IN RTRSEC INTERVAL
MOVEM T1,RTRTIM ;INITIALIZE COUNT-DOWN IN STG
>;END IFN FTOPS20
SKIPN DCNSTA ;IS DECnet TURNED ON?
RET ;NO, NOTHING TO DO
IFN FTOPS10,<
XCT .CPSK0 ;SKIP IF BOOT CPU
RET ;NO, SHOULDN'T BE HERE, BUT JUST RETURN
> ;END IFN FTOPS10
SEC1 ;RUN IN EXTENDED SECTIONS
SETZM RTRSSV ;WE HAVE PROVIDED SERVICE
;Note that we did not get the interlock here; we only tested it.
;The interlock is just to keep this clock level code from changing
;the database while any process level code is running. We may
;get interrupted now by interrupt code, but this won't affect us
;as our critical sections are surronded by D36ON/D36OFF.
SAVEAC <MB,MS,RC,CX,T5,T6> ;SAVE SOME NON-SMASHABLE ACS
CALL RTRTMR ;CALL THE TIMER PROCESSOR, WHICH MAY TURN
; ON RTRRCF
SKIPE RTRRCF ;IS THE RECOMPUTE ROUTING FLAG ON?
CALL RTRRCR ; YES, GO RECOMPUTE THE ROUTING
CALL RTRSRM ;SEND ROUTING MESSAGES IF NEEDED
;CLEAR OWNER OF INTERLOCK
RET ; AND RETURN
SUBTTL RTRJIF - Once a jiffy processing for Router
;RTRJIF - Once a jiffy processing
;
; Call:
; With nothing
;
; Return:
; RET ;ALWAYS
;
; Uses: T1
;
;This routine's only purpose is to service kontroller requests that
;CALKON queues when the request is for a device on the wrong CPU. Since
;this is a TOPS-10 SMP only problem, it does nothing for TOPS-20.
RTRJIF::
IFE FTMP,<RET> ;IF NOT SMP, THIS DOESN'T EXIST.
IFN FTMP,<
SEC1 ;RUN IN SECTION ONE
SAVEAC <RC,MB> ;SAVE SOME ACS TO USE
SKIPA RC,RTRCBQ ;START WITH THE FIRST CIRCUIT BLOCK
RTRJI1: LOAD RC,RCNXT,(RC) ;GET PTR TO NEXT CIRCUIT BLOCK
JUMPE RC,RTN ;NO MORE, JUST RETURN
LOAD T1,LIKON,+RC.LID(RC) ;GET THE POINTER TO THE CIRCUIT BLOCK
CAME T1,.CPCPN ;ARE WE RUNNING ON THE CPU FOR THIS CIRCUIT?
JRST RTRJI1 ;NO, CHECK OUT THE NEXT BLOCK
;Check the circuit's resend queue for any requests that we can queue
;for it now that we are running on the correct CPU.
RTRJI2: ;CHECK IF OTHER CPU HAD KONTROLLER TASKS
; QUEUED UP.
JE RCHLT,(RC),RTRJI3 ;IF NO HALT REQUESTED, SKIP THIS CODE
MOVEI T1,KF.HLT ;KONTROLLER FUNCTION HALT.
MOVE T2,RC ;POINT TO CIRCUIT BLOCK
CALL CALKON ;AND TRY TO DO IT.
JRST RTIDWN ;IF IT FAILS, DECLARE THE CIRCUIT DEAD.
RTRJI3: JE RCINI,(RC),RTRJI4 ;IF NO INITIALIZE REQUESTED, SKIP THIS CODE
MOVEI T1,KF.INI ;THE OTHER CPU DID REQUEST THIS.
MOVE T2,RC ;SET UP POINTER TO CIRCUIT BLOCK
CALL CALKON ;INITIALIZE THE LINE
JRST RTIDWN ;AND DECLARE THE CIRCUIT DOWN.
RTRJI4: SETZRO <RCINI,RCHLT>,(RC) ;CLEAR BITS INDICATING KONTROLLER FUNCTIONS
D36OFF ;TURN OFF INTERRUPTS WHILE PLAYING WITH QUEUES
DEQUE MB,RC.JSQ(RC),MB.NXT,RTRJI6 ;DEQUEUE ANYTHING THAT'S THERE
D36ON ;TURN INTERRUPTS BACK ON
;WE KNOW THAT BY VIRTUE OF GETTING THE MESSAGE
;BLOCK FROM RC.JSQ, RC IS SET UP CORRECTLY.
CALL CALQOB ;SEND THE BLOCK OUT.
JRST RTRJI2 ;SEE IF ANYTHING ELSE ON CIRCUIT'S Q
RTRJI6: D36ON ;TURN THE INTERRUPTS BACK ON
JRST RTRJI1 ; AND CHECK THE NEXT CIRCUIT'S QUEUE
>;End of IFN FTMP
SUBTTL RTRXMT - NSP's Entry in Router
;RTRXMT - Routine to forward Phase III messages from NSP
;
; Call:
; MB/ Ptr to Message Block
; T1/ RQR flag (RT%RQR)
; ODN flag (RT%ODN)
; Public portion of message block must be filled with destination
; and source nodes and output circuit.
;
; Returns:
; RTN ;ALWAYS
;
;This is the only way which an NSP calls router (except for
;initialization). The ODN flag in T1 specifies whether or not NSP
;really wants message back (see FREMSG). The RQR flag specifies
;whether or not NSP is requesting this message be returned.
RTRXMT::SAVEAC <MB,MS,RC> ;SAVE A FEW FOR NSP
MOVX T2,RMRQR ;GET RETURN REQUEST BIT FOR MESSAGE BLK
ANDCAM T2,RM.RQR(MB) ;CLEAR FLAG, ASSUMING NOT INTERESTED
TXNE T1,RT%RQR ;DOES HE WANT IT BACK?
IORM T2,RM.RQR(MB) ;YES, SET BIT IN THE MESSAGE BLK
MOVX T2,RMODN ;GET "NSP WANTS MSG BACK" BIT
ANDCAM T2,RM.ODN(MB) ;CLEAR FLAG, ASSUMING CALLER NOT INTERESTED
TXNE T1,RT%ODN ;DOES HE WANT OUTPUT DONE CALL?
IORM T2,RM.ODN(MB) ;YES, SET FLAG FOR FREMSG AND R2NODN
SETZRO RMICP,(MB) ;THERE'S NO INPUT CIRCUIT BLK PTR
SETZRO RMOCP,(MB) ;THERES NO OUTPUT CIRCUIT BLK PTR
SETZRO RMVST,(MB) ;ZERO VISITS COUNT
SETONE RMMB1,(MB) ;BIT THAT MUST BE ONE IN FIRST BYTE
SKIPN DCNSTA ;IS DECNET RUNNING?
CALLRET FREMSG ;NO, PUNT THE MESSAGE CORRECTLY AND LEAVE
LOAD T1,MBDST,(MB) ;GET DESTINATION NODE NUMBER
CAMLE T1,RTRMXN ;IS NUMBER REASONABLE?
CALLRET FREMSG ;NO, PUNT IT.
LOAD T1,MBSRC,(MB) ;GET SOURCE NODE NUMBER
ADD T1,RTRNRV ;ADD OFFSET TO NORMAL ROUTING VECTOR
TMNN RNLCL,(T1) ;IS THIS A LOCAL NODE?
BUG.(CHK,ROUBSN,ROUTER,SOFT,<Bad source node in message from NSP>,,<
Cause: This BUG is not documented yet.
>,FREMSG)
LOAD T1,MBCHN,(MB) ;GET CHANNEL NUMBER
JUMPE T1,RTRFWD ;IF NO LOOP BACK CIRCUIT SPECIFIED BY
;SESSION CONTROL, DON'T SET CIRCUIT PTR
CALL RTRGCB ;YES, TRANSLATE INTO A CIRCUIT BLK PTR
BUG.(CHK,ROUILS,ROUTER,SOFT,<Illegal Circuit Specified in NSP msg>,,<
Cause: This BUG is not documented yet.
>,FREMSG)
STOR RC,RMOCP,(MB) ;STORE IT AS OUTPUT CIRCUIT
CALLRET RTRFWD ;LOOKS REASONABLE, FORWARD MESSAGE
SUBTTL RTRFWD - Perform Routing of Message
;RTRFWD - Routine to do routing
;
; Call:
; MB/ Ptr to Message Block
;
; Return:
; RTN ;ALWAYS
;
; Uses T1-T3
;
;This routine takes an input message, checks its Router header and
;routes it to the correct destination using the "normal" routing
;vector. The relavent fields in the public section of the Message
;Block must have been set up.
RTRFWD: XMOVEI T1,RM.MSD(MB) ;GET THE POINTER TO THE ROUTER MSD
CALL DNPINI ;AND DNPINI IT
LOAD T1,RMFST,(MB) ;GET THE FIRST BYTE OF MESSAGE
CALL DNP1BY ;PUT IT IN MESSAGE HEADER AREA
LOAD T1,MBDST,(MB) ;GET THE DESTINATION
CALL DNP2BY ;STORE IT AWAY
LOAD T1,MBSRC,(MB) ;GET THE SOURCE
CALL DNP2BY ;PUT IN MESSAGE
LOAD T1,RMVST,(MB) ;GET VISITS BYTE
CALL DNP1BY ;AND PUT THAT IN, TOO
MOVE T1,MB ;GET POINTER TO THE MESSAGE BLOCK
CALL DNRPOS ;GET CURRENT POSITION IN THE BLOCK
STOR T1,RMMK1,(MB) ;AND SET MARK IN BLOCK
RTRFW1: JN RMOCP,(MB),RTR2RM ;IF OUTPUT CIRCUIT WAS SPEC'D, FORWARD IT
LOAD T1,MBDST,(MB) ;GET THE DSTNODE ADDRESS
SKIPLE T1 ;RANGE CHECK THE DESTINATION
CAMLE T1,RTRMXN ;GREATER THAN THE MAX NODE ADDRESS?
JRST RTRFOR ;DEST IS OUT OF RANGE
ADD T1,RTRNRV ;GET OFFSET INTO NORMAL ROUTING VECTOR
TMNN RNRCH,(T1) ;IS IT REACHABLE?
JRST RTRFUR ;NODE IS UNREACHABLE
TMNE RNLCL,(T1) ;IS THIS A LOCAL MESSAGE?
JRST RTRFLC ;YES, FORWARD TO LOCAL NSP (OR WHATEVER)
ADD T1,RTROFS ;POINT TO OUTPUT CIRCUIT VECTOR ENTRY
MOVE T1,(T1) ;GET THE OUTPUT CIRCUIT
STOR T1,RMOCP,(MB) ;STORE OUTPUT CIRCUIT ADDRESS FOR NEXT TIME
CALLRET RTRFW1 ;TRY TO FORWARD THE MESSAGE
;Here when destination node is out-of-range.
RTRFOR: TMNE RMRQR,(MB) ;WAS RETURN REQUESTED
JRST RTRFRT ;YES, RETURN IT
OPSTR <SKIPN T2,>,RMICP,(MB) ;GET THE CIRCUIT IT CAME IN ON.
BUG.(CHK,ROUNSO,ROUTER,SOFT,<NSP sent out-of-range packet>,,<
Cause: This bug is not documented yet
>,FREMSG)
LOAD T2,RCLID,(T2) ;GET THE LINE ID
EVENT RE.NOR,<Node out-of-range packet loss>,MB
AOS RTRCNO ;INCREMENT OUT-OF-RANGE COUNT
CALLRET FREMSG ;RETURN THE MSG BLK
;Here when destination node is unreachable.
RTRFUR: TMNE RMRQR,(MB) ;WAS RETURN REQUESTED?
JRST RTRFRT ;WE HAVE TO RETURN MESSAGE
OPSTR <SKIPE T2,>,RMICP,(MB) ;GET THE CIRCUIT IT CAME IN ON
LOAD T2,RCLID,(T2) ;GET THE LINE ID FOR IT
EVENT RE.NUR,<Node unreachable packet loss>,MB
AOS RTRCNU ;INCREMENT EXECUTOR NODE COUNTER
CALLRET FREMSG ;GIVE THE MESSAGE BACK AND RETURN
;Here to return message to sender due to unreachability.
RTRFRT: ETRACE RTR,<Returning message due to unreachability>
CALL RTRERH ;EAT THE ROUTER HEADER WE PUT ON THE MESSAGE
SETZRO RMRQR,(MB) ;ZERO THE RQR FLAG
SETONE RMRTS,(MB) ;SET THE RETURN TO SENDER FLAG
LOAD T1,MBDST,(MB) ;GET THE DST ADDR
LOAD T2,MBSRC,(MB) ; AND THE SRC ADDR
STOR T2,MBDST,(MB) ;SWITCH THEM
STOR T1,MBSRC,(MB) ; AROUND
TMNN RMICP,(MB) ;THIS MSG COME FROM LOCAL NSP?
JRST [CALL CPYMSG ;YES, MAKE THIS MSG LOOK LIKE AN INPUT
; BY COPYING SEGMENTS TOGETHER
CALLRET FREMSG ;OOPS, COULDN'T GET MSG BLOCK, FORGET IT
EXCH T1,MB ;POINT TO THE NEW MSG IN MB
CALL DNFMSG ;FREE THE OLD MSG
CALLRET R2NRTN] ; AND RETURN THE NEW MSG
CALLRET RTRFWD ;TRY TO FORWARD AGAIN
;Here when the message is for a local NSP.
RTRFLC: OPSTR <SKIPGE RC,>,RMICP,(MB) ;SEE WHERE MSG CAME FROM
JRST RTRF2N ;IF ICP IS NEG, MSG HAS BEEN TURNED
; AROUND FROM NSP
JUMPE RC,RTRF2C ;IF ICP IS ZERO, MSG IS FROM NSP,
; SO WE HAVE TO COPY DATA
;IF ICP IS NON-ZERO, MSG IS FROM
; OUTSIDE & JUST FALL THROUGH
;We are here when we have to pass an incoming message to NSP.
INCR RCCAP,(RC) ;INCR ARRIVING PACKETS RECEIVED (TO NSP)
RTRF2N: TMNE RMRTS,(MB) ;IS THIS A RETURNED MESSAGE?
CALLRET R2NRTN ;YUP, DO SO.
CALLRET R2NRCV ;NO, THIS IS GOOD OLDE RECEIVED DATA
RTRLTR:: ;LABEL FOR DNSNUP TO FIND LOCAL MESSAGES
RTRF2C: CALL RTRERH ;EAT THE ROUTING HEADER
CALL CPYMSG ;COPY THE MSD'S TOGETHER
CALLRET FREMSG ;DON'T CARE IF IT FAILS, THEN FREE IT UP
PUSH P,T1 ;SAVE THE POINTER TO THE NEW MESSAGE
CALL FREMSG ;RETURN THE ORIGINAL TO NSP
POP P,MB ;AND WE CAN DIDDLE WITH OUR NEW COPY
JRST RTRF2N ;NOW PASS THE MESSAGE ON TO NSP
;
; Get some bytes that we put in the router MSD above. This was to fix problems
; with Event processing, But the local NSP and the Return to sender code does
; not expect these fields to be set up. So we will punt them here.
RTRERH: LOAD T1,MBFMS,(MB) ;GET THE POINTER TO THE FIRST MSD
XMOVEI T2,RM.MSD(MB) ;AND THE ADDRESS OF THE ROUTER MSD
CAME T1,T2 ;DOES IT AGREE?
RET ;RETURN TO CALLER
LOAD T1,MDNXT,+RM.MSD(MB) ; GET THE POINTER TO THE NEXT MSD
STOR T1,MBFMS,(MB) ;SAVE AS FIRST MSD POINTER
RET ;RETURN TO CALLER
SUBTTL RTR2RM - Send Message to Remote Node
;RTR2RM - Queue Out Message to Remote through the DLL
;
; Call:
; MB/ Ptr to message block
;
; Return:
; RET ;ALWAYS
;
; Uses: P1-P2, T1-T3
RTR2RM: LOAD RC,RMOCP,(MB) ;SET UP RC WITH OUTPUT CIRCUIT PTR
LOAD T1,RCSTA,(RC) ;GET THE CIRCUIT'S STATE
CAIE T1,RCS.RN ;IS IT RUNNING
CAIN T1,RCS.TT ; OR IN TEST?
TRNA ;YES, WE CAN FORWARD THE PACKET
CALLRET FREMSG ;NO, DESTROY THE PACKET
JE RMICP,(MB),[INCR RCCDP,(RC) ;IS THE PACKET FROM OUR LOCAL NSP?
JRST RTR2R1] ;YES, INCREMENT COUNT OF NSP PACKETS
; AND SEND MSG WITHOUT WORRYING ABOUT
; SQUARE-ROOT LIMIT AND AGED PACKET LOSS
;We now check the "square-root" limit criterion, to see if the message
;should be discarded. We check this by comparing the number of message
;blocks queued out on this circuit with the number of message blocks that
;the memory manager has guaranteed router divided by the square-root
;of the number of circuits (We simplify things by just using the number
;of circuits divided by two, which is close enough for a small number of
;circuits).
INCR RCCTR,(RC) ;NO, INCREMENT THE TRANSIT PACKETS RECEIVED
LOAD RC,RMOCP,(MB) ;GET THE CIRCUIT BLOCK POINTER
CALL DNNMSG ;GET NUMBER OF MESSAGE BLOCKS AVAILABLE
MOVE T2,RTRNLN ;FIND THE NUMBER OF CIRCUITS IN USE
ASH T2,-1 ;DIVIDE BY TWO
IDIV T1,T2 ;DIVIDE TO FIND THE QUEUE THRESHOLD
OPSTR <CAMLE T1,>,RCCMQ,(RC) ;COMPARE WITH THE NUMBER OF MSG BLKS QUEUED
JRST RTR2R0 ;WE DON'T HAVE TO FLUSH IT
;Here to discard a message that has execeded the "square-root" limit.
TRACE RTR,<Congestion Loss on output>
INCR RCCTL,(RC) ;INCREMENT THE CONGESTION LOSS COUNTER
CALLRET FREMSG ;FREE THE MESSAGE AND RETURN
;Check the visit field for a over-aged message.
RTR2R0: LOAD T1,RMFST,(MB) ;GET THE FIRST BYTE OF MESSAGE
OPSTRM <AOS T2,>,RMVST,(MB) ; AND UPDATE AND GET VISITS FIELD
MOVE T3,RTRMXV ;THIS IS THE MAXIMUM VISITS COUNT ALLOWED
TXNE T1,RM%RTS ;IS THIS GOING TO COMING BACK?
ASH T3,2 ;GIVE IT TWICE AS MANY HOPS
CAMG T2,T3 ;IS IT AGED TO FAR?
JRST RTR2R1 ;NO, PUT HEADER ON MSG
;Here to report a aged packet loss event.
SETZ T2, ;THIS EVENT HAS NO ENTITY ASSOCIATED WITH IT
EVENT RE.APL,<Aged packet loss event>,MB
AOS RTRCAP ;INCREMENT THE AGED PACKET COUNTER
CALLRET FREMSG ;FREE THE MESSAGE AND RETURN
;All packets to be sent come through here.
RTR2R1: LOAD T1,RCNTY,(RC) ;GET THE NODE TYPE
CAIN T1,RCT.P2 ;IS IT A PHASE II NODE?
JRST RTR2R3 ;YES, DON'T PUT ON A RTR HDR
;Now we have to diddle with the MSD pointers slightly to convince
;the DLL not to get the router header from the input MSD.
XMOVEI T1,RM.MSD(MB) ;POINT TO THE TRANSPORT MSD
STOR T1,MBFMS,(MB) ;STORE IN FIRST MSD SLOT
RTR2R3: JE RMICP,(MB),RTR2R4 ;DID IT COME FROM A REMOTE NODE?
INCR RCCTS,(RC) ;IT DID, INCREMENT TRANSIT COUNT
LOAD T1,MDPTR,+IN.MSD(MB) ;ALSO GET THE DYNAMIC BYTE POINTER
STOR T1,MDAUX,+IN.MSD(MB) ; AND STORE IT IN THE ORIGNAL BYTE POINTER
; SO THE DLL DOESN'T USE THE OLD ROUTER
; HEADER, WHICH WE JUST STRIPED AWAY
;Now set up the arguments for the kontroller call and queue it out.
RTR2R4: INCR RCCMQ,(RC) ;INCREMENT NUMBER OF MESSAGES QUEUED
MOVX T1,KF.QOB ;GET QUEUE OUTPUT BUFFER FUNCTION CODE
LOAD T2,RMOCP,(MB) ;GET OUTPUT CIRCUIT
MOVE T3,MB ;POINT TO MB
CALL CALKON ;CALL THE KONTROLLER
CALL [CALL RTIDWN ;SAY THE LINE IS NOW DOWN
MOVE T3,MB ;SET UP MESSAGE BLOCK POINTER FOR RTIOTC
CALLRET RTIOTC] ;FREE UP THE MESSAGE BLOCK
RET ;GIVE A GOOD RETURN TO CALLER
SUBTTL R2NODN - Return Output Done to NSP
;R2NODN - Give Output Done to NSP
;
; Call:
; MB/ Pointer to Message Block
;The relevant fields must be set up in the public portion of the message
;block (i.e., source and destination node addresses, etc.)
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
R2NODN: MOVX T3,NV.ODN ;GET THE OUTPUT DONE ENTRY TYPE
MOVE T4,MB ;SET UP MB FOR NSP
LOAD T1,MBSRC,(MB) ;IT'S GOING BACK TO SOURCE
CALLRET R2NCL1 ;CALL NSP
SUBTTL R2NRTN - Return Message to NSP
;R2NRTN - Return Message to NSP
;
; Call:
; MB/ Pointer to Message Block
;Fields must be set up correctly in the Public portion of the message
;block.
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
R2NRTN: MOVX T3,NV.RTS ;GET THE RETURNING TYPE
CALLRET R2NCAL ;MERGE WITH THE OTHER CODE
SUBTTL R2NRCV - Pass Recieved Message to NSP
;R2NRCV - Pass recieved message to router user (ususally NSP)
;
; Call:
; MB/ Pointer to Message Block
;Fields must be set up correctly in the public portion of the message
;block.
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
;
;R2NCAL, which is the actual routine which calls a router user (also called
;an NSP), will check the message block for the destination address and use
;this to find look up the correct entry vector in the normal routing vector.
;RTRNOV contains the entry vector for NSP when the node entry for RTRNRV
;says it is a local node (RNLCL is on).
R2NRCV: MOVX T3,NV.RCV ;GIVE RECIEVED MESSAGE ENTRY TYPE
R2NCAL: SKIPN T4,MB ;HE WANTS THE MESSAGE BLOCK PTR IN T4
BUG.(CHK,ROUXNZ,ROUTER,SOFT,<R2NCAL called with MB=0>,,<
Cause: This BUG is not documented yet.
>,RTN)
LOAD T1,MBDST,(MB) ;GET THE DESTINATION OF THIS MESSAGE
SKIPLE T1 ;RANGE CHECK THE
CAMLE T1,RTRMXN ; FOR REASONABLENESS
BUG.(CHK,ROUNOR,ROUTER,SOFT,<Node number out of range>,,<
Cause: This BUG is not documented yet.
>,R2NCLE)
R2NCL1: ADD T1,RTRNRV ;GET NODE'S ENTRY IN "NORMAL" VECTOR
JN RNLCL,(T1),R2NCL2 ;IF IT IS A LOCAL NODE, RETURN MESSAGE
TMNE RMODN,(MB) ;NOT LOCAL, CHECK FLAGS FOR CONSISTENCY
BUG.(CHK,ROUNLN,ROUTER,SOFT,<Trying to return msg to non-local NSP>,,<
Cause: This BUG is not documented yet.
>,R2NCLE)
R2NCLE: SETZRO RMODN,(MB) ;MAKE FREMSG TOSS THE MSG NOW
CALLRET FREMSG ;RETURN MSG BLK TO FREE POOL
R2NCL2: ADD T1,RTROFS ;GET THE VECTORED ENTRY POINT POINTER
SKIPN T1,(T1) ;GET THE CORRECT ENTRY
BUG.(CHK,ROUCNL,ROUTER,SOFT,<Trying to call non-existant NSP>,,<
Cause: This BUG is not documented yet.
>,R2NCLE)
CALLRET (T1) ;CALL WHATEVER IS ABOVE US
SUBTTL R2KINI - Initialize a Kontroller's Circuit
;R2KINI - Initialize a DLL circuit
;
; Call:
; RC/ Pointer to Circuit Block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T2
R2KINI: MOVX T1,RCS.WT ;SAY THAT WE ARE IN
STOR T1,RCSTA,(RC) ;WAIT STATE
MOVX T1,KF.INI ;KONTROLLER FUNCTION IS INITIALIZE
MOVE T2,RC ;POINTER TO CIRCUIT BLOCK
CALL CALKON ;CALL THE KONTROLLER
CALLRET RTIDWN ;CIRCUIT IS DOWN
RET ;GIVE GOOD RETURN ABOVE
SUBTTL R2KHLT - Halt the Kontroller's Circuit
;R2KHLT - Halt a DLL circuit
;
; Call:
; RC/ Pointer to Circuit Block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T2
;
;We have to set the state of the circuit to wait state.
R2KHLT: MOVX T1,RCS.OF ;WE ARE IN "OFF" STATE
STOR T1,RCSTA,(RC) ;STORE THIS STATE
MOVX T1,KF.HLT ;FUNCTION IS HALT
MOVE T2,RC ;POINTER TO CIRCUIT BLOCK
CALL CALKON ;CALL THE KONTROLLER
CALLRET RTIDWN ;CIRCUIT IS DOWN
RET ;RETURN TO CALLER GOOD
SUBTTL CALKON - Call the Kontroller
;CALKON - Call the DLL level "kontroller"
;
; Call:
; T1/ Kontroller Function Code
; T2/ Pointer to circuit block
; T3/ Argument (Usually Pointer to Message Block)
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
;
;This routine will call the correct Kontroller on the correct circuit
;given the line id. The kontroller is called with T1 containing the
;function to perform, T2 containing the hardware line address and T3
;with function specific data. If the device is on the wrong CPU (only
;on TOPS-10 SMP), CALKON will queue the request to be serviced
;at once-a-jiffy service on the correct CPU.
CALKON: SAVEAC <RC,P1> ;SAVE A COUPLE ACS
MOVE RC,T2 ;SET UP THE CIRCUIT BLOCK POINTER
IFN FTMP,<
LOAD T4,LIDEV,+RC.LID(RC) ;GET THE DEVICE TYPE
CAIN T4,LD.DDP ;IS IT NOT CPU-DEPENDANT?
JRST CALKO5 ;NOT CPU DEPENDANT, GO AHEAD AND DO IT.
LOAD T4,LIKON,+RC.LID(RC) ;GET THE CPU NUMBER OF THE CIRCUIT
CAMN T4,.CPCPN ;ARE WE ON THAT CPU NOW?
JRST CALKO5 ;YES
CAIN T1,KF.QOB ;QUEUED OUTPUT?
JRST CALKO4 ;YES, QUEUE UP THE MESSAGE BLOCK.
CAIE T1,KF.INI ;IS THIS AN INITIALIZE FUNCTION?
JRST CALKO1 ;NO, TRY FOR SOMETHING ELSE
SETONE RCINI,(RC) ;FLAG INITIALIZE TO BE DONE AT JIFFY LEVEL.
RETSKP ;SAY WE DID IT.
CALKO1: CAIE T1,KF.HLT ;IS THIS A HALT KONTROLLER FUNCTION?
BUG.(CHK,ROUIKF,ROUTER,SOFT,<Illegal Kontroller function>,,<
Cause: CALKON was called with an illegal function code. The only allowed
values are KF.QOB, KF.INI, and KF.HLT.
>,RTN)
SETONE RCHLT,(RC) ;FLAG HALT TO BE DONE AT JIFFY LEVEL.
RETSKP ;SAY WE DID IT
CALKO4: D36OFF ;NO, WE'LL HAVE TO QUEUE THE MESSAGE
ENDQUE T3,RC.JSQ(RC),MB.NXT,T1 ;QUEUE THE MESSAGE
D36ON ;TURN INTERRUPTS BACK ON
RETSKP ; AND RETURN TO SENDER
CALKO5:
>;End of IFN FTMP
LOAD T2,RCKBA,(RC) ;GET THE KONTROLLER'S BLOCK ADDRESS
LOAD P1,LIDEV,+RC.LID(RC) ;GET THE DEVICE TYPE
SKIPL P1 ;RANGE CHECK THE DEVICE TYPE
CAILE P1,LD.MAX ; FOR REASONABLENESS
BUG.(CHK,ROUNSD,ROUTER,SOFT,<Tried to call non-existant device driver>,,<
Cause: This BUG is not documented yet.
>,RTN)
RTROTR:: ;LABEL FOR DNSNUP TO FIND OUTPUT MESSAGES
IFN FTOPS10, MOVX T4,DD.DEC ;WE ARE DECNET TALKING
CALL @KONDSP(P1) ;DISPATCH TO KONTROLLER BASED ON LINE TYPE
RET ;GIVE ERROR RETURN
RETSKP ;GOOD RETURN
SUBTTL CALQOB - Call CALKON for queued output.
;CALQOB - Send a message to the DLL "kontroller"
;
; Call:
; RC/ Pointer to the circuit block
; MB/ Pointer to message block
; Return:
; +1, Always. If the output fails, it calls RTIDWN and then
; RTIOTI for the message block in MB.
;
;This routine is a jacket around CALKON to make the code sending messages
;simpler and easier to read.
CALQOB:
MOVEI T1,KF.QOB ;SET UP FUNCTION CODE
MOVE T2,RC ;COPY POINTER TO CIRCUIT BLOCK
MOVE T3,MB ;COPY POINTER TO MESSAGE BLOCK
CALL CALKON ;CALL THE KONTROLLER
TRNA ;FAILED, DO EXTRA WORK
RET ;RETURN SUCCESS
CALL RTIDWN ;KILL THE CIRCUIT
MOVE T3,MB ;POINTER TO THE MESSAGE BLOCK
CALLRET RTIOTC ;RETURN MESSAGE BLOCK AND RETURN.
SUBTTL RTRRCR - Recompute Routing
;RTRRCR - Routine to Recompute Routing Vector
;
; Call:
; RTRNRV is expected to contain a ptr to the current "normal"
;routing vector, while RTRSRV points to a scratch routing vector.
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T6
;
; AC Usage:
; RC/ Ptr to circuit block
; MB/ Ptr to message block used for routing message
; T4/ Index into scratch routing vector
; T3/ Index into normal routing vector
;
;This routine is called whenever it is thought that the topology of
;the network may have changed. RTRNRV is the normal routing vector
;which is used by the forwarding routine, while RTRSRV is a scratch
;routing vector which this routine uses to compute the new routing
;vector.
RTRRCR: TRACE RTR,<Recomputing network topology>
SAVEAC <P1,P2,RC,MB>
SETZM RTRRCF ;CLEAR THE "RECOMPUTE-ROUTING" FLAG
MOVE T2,RTRSRV ;POINT TO THE SCRATCH ROUTING VECTOR
XMOVEI T1,1(T2) ;START AT FIRST NODE
ADD T2,RTRMXN ;ADD MAX NODE NUMBER FOR END OF SMEAR
MOVX T3,RNHOP!RNCST ;SMEAR WITH MAXIMUM HOPS AND COST
CALL DNSWDS ;SMEAR SCRATCH VECTOR WITH MAX
MOVE RC,RTRCBQ ;GET PTR TO FIRST CIRCUIT BLOCK
RTRRC1: JUMPE RC,RTRRC5 ;IF NO MORE CIRCUIT BLOCKS, CHECK LOCAL
LOAD T1,RCSTA,(RC) ;GET THE CIRCUIT STATE
CAIE T1,RCS.RN ;ARE WE IN RUN STATE
CAIE T1,RCS.TT ; OR MAINT STATE?
TRNA ;YES, CHECK THIS CIRCUITS ROUTING MESSAGE
JRST RTRRC4 ;NO, CHECK THE NEXT CIRCUIT
;Now check to see if the neighbor on this circuit is a Phase II node. If
;he is, just set the RNRCH bit in the routing vector and leave the hops
;and cost infinite, so that we won't tell anybody about him in our
;routing messages.
LOAD T1,RCNTY,(RC) ;GET THE NODE TYPE
CAIN T1,RCT.3F ;IS HE A FULL ROUTING NODE?
JRST RTRRC9 ;YES, PROCESS AS A PHASE III
LOAD T2,RCNAD,(RC) ;YES, GET HIS NODE NUMBER
ADD T2,RTRSRV ;POINT TO ENTRY IN THE SCRATCH VECTOR
SETONE RNRCH,(T2) ;HE IS NOW REACHABLE
CAIE T1,RCT.3S ;IS THIS A SMALL (NONROUTING) PHASE III?
JRST RTRR1A ;NO, JUST PHASE II
;FOR PHASE III NON-ROUTING
LOAD T1,RCCST,(RC) ;GET COST TO NODE
STOR T1,RNCST,(T2) ;STORE IN ROUTING VECTOR
MOVEI T1,1 ;GET HOPS TO NODE (ACROSS THIS CIRCUIT, 1)
STOR T1,RNHOP,(T2) ;STORE IN ROUTING VECTOR
RTRR1A: ADD T2,RTROFS ;NOW FIND THE OUTPUT CIRCUIT ENTRY
MOVEM RC,(T2) ;STORE CIRCUIT POINTER IN VECTOR
;Here to re-use the last routing message.
RTRRC9:
;Note that we do not use OPSTR for the following exchange, as OPSTR
;may expand to a multi-word sequence. The EXCH is used so that we do
;not have to get the interlock. Interrupt level code that deals with
;LRM will not see the LRM pointer, and thus will not free it.
IFN RCLRM+1,<PRINTX ?RCLRM must be a full word pointer>
SETZ MB, ;ZERO THE LAST ROUTING MSG PTR IN
EXCH MB,RC.LRM(RC) ; THE CIRCUIT BLOCK AND PICK UP THE NEW ONE
JUMPE MB,RTRRC4 ;IF NONE, GO TO NEXT CIRCUIT
MOVE T1,MB ;POINT TO THE MESSAGE BLOCK
CALL DNGINI ;GET UP TO GET BYTES
LOAD T1,RMMK2,(MB) ;GET THE ROUTING DATA'S POSITION
CALL DNGPOS ; AND GO TO IT
MOVE T1,MB ;POINT TO MESSAGE BLOCK AGAIN
CALL DNLENG ;GET THE LENGTH OF THE MESSAGE
SUBI T1,2 ;ACCOUNT FOR CHECKSUM
ASH T1,-1 ;MAKE IT AN ENTRY (NODE) COUNT
SKIPLE T1 ;CHECK LENGTH OF STORED ROUTING MESSAGE
CAMLE T1,RTRMXN ;OF REASONABLE LENGTH?
BUG.(CHK,ROURML,ROUTER,SOFT,<Stored routing message format error in RTRRCR>,,<
Cause: This BUG is not documented yet.
>,RTRRC4)
MOVE T3,T1 ;GET COUNT OF ENTRYS
MOVE P1,RTRSRV ;GET POINTER TO SCRATCH VECTOR
ADDI P1,1 ;OFFSET FROM FIRST NODE
;RTRRCR - Continued from last page
RTRRC2: CALL DNG2BY ;GET THE BYTE FOR A NODE
BUG.(CHK,ROUUER,ROUTER,SOFT,<Unexpected end of routing message>,,<
Cause: This BUG is not documented yet.
>,RTRRC4)
LOAD T2,RGCST,+T1 ;GET THE COST FROM THE BYTE
OPSTR <ADD T2,>,RCCST,(RC) ; ADD THE CIRCUIT COST
LOAD T1,RGHOP,+T1 ;GET THE HOP COUNT
ADDI T1,1 ;ADJUST IT BY US
CAMG T2,RTRMXC ;IS THE COST WITHIN THE MAX?
CAMLE T1,RTRMXH ; HOW ABOUT THE HOPS?
JRST RTRRC3 ;NO, LEAVE IT AT THE MAX
LOAD T4,RNCST,(P1) ;GET THE BEST COST SO FAR
CAMLE T2,T4 ;SEE IF IT'S AS GOOD AS NEW COST
JRST RTRRC3 ; IT'S NOT, DON'T BOTHER CHANGING IT
STOR T1,RNHOP,(P1) ;IT'S BETTER, STORE THE HOPS
STOR T2,RNCST,(P1) ; AND THE COST
SETONE RNRCH,(P1) ;SAY WE CAN REACH HIM
MOVE T1,P1 ;GET A COPY OF ENTRY POINTER FOR NRV
ADD T1,RTROFS ;FIND OUTPUT CIRCUIT ENTRY POINTER
MOVEM RC,(T1) ;STORE THE OUTPUT CIRCUIT
RTRRC3: AOJ P1, ;INCREMENT THE POINTER
SOJG T3,RTRRC2 ; AND LOOP UNTIL FINISHED WITH THEM ALL
RTRRC4: D36OFF ;TURN OFF INTERRUPTS FOR A MOMENT
LOAD T1,RCLRM,(RC) ;GET THE POSSIBLY NEW MB POINTER
JUMPN T1,[D36ON ;IF GOT A NEW ROUTING MSG, WE'LL HAVE
CALL FREMSG ; TO GET RID OF THE OLD ONE
JRST RTRR11] ; AND MERGE WITH OTHER CODE
STOR MB,RCLRM,(RC) ;PUT PTR BACK TO THE WAY IT WAS
D36ON ;TURN INTERRUPTS BACK ON
RTRR11: LOAD RC,RCNXT,(RC) ;GET THE NEXT CIRCUIT
JUMPN RC,RTRRC1 ; UNTIL WE GET THEM ALL
;Here to go through and compare the two routing vectors. We also
;look for local users in the "normal" routing vector as we go
;through. With local users, RTRNOV has the address of the vector entry
;to that "NSP", therefore it is left alone.
RTRRC5: MOVE T3,RTRMXN ;GET THE COUNT OF NODES
MOVE P1,RTRSRV ;POINTER TO SCRATCH ROUTING VECTOR
ADDI P1,1 ;START WITH NODE 1
MOVE P2,RTRNRV ;POINTER TO NORMAL ROUTING VECTOR
ADDI P2,1 ;START WITH FIRST NODE
SETZB T2,T4 ;T2 := CHECKSUM, T4:= # OF UPDATES
RTRRC6: MOVE T1,(P2) ;GET THE NORMAL ENTRY FOR NODE
JN RNLCL,+T1,[MOVEM T1,(P1) ;IF ITS A LOCAL NODE,
MOVE T1,P2 ;GET COPY OF NRV ENTRY
ADD T1,RTROFS ;FIND THE OUTPUT VECTOR ENTRY
MOVE T1,(T1) ;GET THE OUTPUT CIRCUIT
ADD P1,RTROFS ;FIND THE OUTPUT VECTOR ENTRY
MOVEM T1,(P1) ;STORE THE OUTPUT CIRCUIT
SUB P1,RTROFS ;POINT BACK TO THE OUTPUT VECTOR
JRST RTRRC7] ; JUST UPDATE THE LOCAL ENTRY IN SCRATCH
CAME T1,(P1) ;COMPARE IT TO THE SCRATCH ENTRY
AOJ T4, ;IF THEY ARE DIFFERENT, INCREMENT COUNT
LDB T1,[POINTR ((P1),<RNHOP!RNCST>)] ;HOP AND COST MUST BE ADJACENT
ADD T2,T1 ;SUM THE CHECKSUM
RTRRC7: AOJ P1, ;LOOK AT NEXT "SCRATCH" ENTRY
AOJ P2, ; AND NEXT "NORMAL" ENTRY
SOJG T3,RTRRC6 ;LOOP OVER ALL ENTRIES
MOVE T1,T2 ;GET COPY OF CHECKSUM
CALL CKSNRM ;FIXUP THE CHECKSUM
MOVEM T1,RTRCKS ;DONE, STORE THE CHECKSUM
JUMPE T4,RTN ;IF NO CHANGES, JUST RETURN
TRACE RTR,<Network topology change occured - changing routing vector>
D36OFF ;NO INTERRUPTS
MOVE T1,RTRSRV ;GET POINTER TO SCRATCH REACHABILITY VECTOR
EXCH T1,RTRNRV ;SWITCH THE SCRATCH AND THE NORMAL
MOVEM T1,RTRSRV ;USE THE OLD NORMAL VECTOR AS THE SCRATCH
MOVE T1,RTRSOV ;GET POINTER TO SCRATCH OUTPUT-CIRC VECTOR
EXCH T1,RTRNOV ;SWITCH THE SCRATCH AND NORMAL
MOVEM T1,RTRSOV ;USE THE OLD NORMAL VECTOR AS THE SCRATCH
D36ON ;GIVE UP INTERLOCK
IFN FTOPS20,<CALL NTCIN> ;INVOKE NETWORK TOPOLOGY CHANGE INTERRUPT
MOVE RC,RTRCBQ ;GET PTR TO FIRST CIRCUIT BLOCK
JUMPE RC,RTN ;NO CIRCUITS? JUST RETURN
RTRRC8: SETONE RCSRM,(RC) ;SET THE "SEND ROUTING MESSAGE" FLAG
LOAD RC,RCNXT,(RC) ;GET THE NEXT CIRCUIT
JUMPN RC,RTRRC8 ;GO SET SRM, IF ANOTHER ONE IS THERE
RET ;RETURN
SUBTTL RTRSRM - Send routing messages if needed
;RTRSRM - Routine to send routing messages out on a circuit if needed
;
; Call:
; RTRNRV must contain the ptr to the normal routing vector
; RTRCBQ must contain a ptr to the first circuit block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T5
;We go through all the circuit blocks and see if the long timer has
;expired (T2). If it has we send a routing message, if it hasn't check
;the send routing message flag and if set, send the routing message if
;the short timer has expired. The routing message is build from the
;"normal" routing vector. After the routing message has been queued,
;the circuit block "last routing message sent" timer is updated, and
;the "send routing message" flag is cleared.
RTRSRM: SAVEAC P1 ;SAVE AN PEA
SKIPA RC,RTRCBQ ;GET THE FIRST CIRCUIT POINTER
RTRSR1: LOAD RC,RCNXT,(RC) ;GET THE NEXT CIRCUIT BLOCK
JUMPE RC,RTN ;IF NONE LEFT, JUST LEAVE
LOAD T1,RCNTY,(RC) ;GET THE NODE TYPE
CAIE T1,RCT.3S ;PHASE III NON-ROUTING NODES DON'T GET THEM
CAIN T1,RCT.P2 ;IS THE NEIGHBOR A PHASE II?
JRST RTRSR1 ;YES, TRY NEXT CIRCUIT
CALL DNGTIM ;GET CURRENT TIME
MOVE T2,RTRTM1 ;ASSUME THE LONG TIME
TMNE RCSRM,(RC) ;IS THE "SEND ROUTING MSG" FLAG ON?
IDIVI T2,^D30 ;YES, USE THE SHORT TIMER (%RTTM2)
OPSTR <ADD T2,>,RCTLR,(RC) ;ADD IN THE LAST TIME WE SEND ONE
CAMLE T2,T1 ;SEE IF ITS TIME TO SEND ONE
JRST RTRSR1 ;NOT ON THIS CIRCUIT, TRY NEXT ONE
LOAD T1,RCSTA,(RC) ;GET THE STATE OF THIS CIRCUIT
CAIE T1,RCS.TT ;IS THE STATE IN TEST
CAIN T1,RCS.RN ; OR OK STATE
TRNA ;YES, SEND ROUTING MESSAGE
JRST RTRSR1 ;NO, LOOK AT NEXT CIRCUIT
;Here when we are about to send a routing message out on a circuit.
MOVE T1,RTRMXN ;USE MAX NODE NUMBER TO CALCULATE SIZE OF MSG
LSH T1,1 ;MAKE IT INTO BYTES
ADDI T1,2 ;SPACE FOR CHECKSUM
CALL DNGMSG ;GET A MESSAGE BLOCK AND STUFF
JRST RTRSR1 ;COULDN'T GET MESSAGE BLOCK, TRY NEXT CIRCUIT
MOVE MB,T1 ;GET POINTER TO MESSAGE BLOCK
XMOVEI T1,UD.MSD(MB) ;GET POINTER TO USER DATA MSD
CALL DNPINI ;INITIALIZE THE MSD AND HEADER
MOVE T3,RTRMXN ;COUNT TO USE FOR GOING THROUGH RTRNRV
MOVE P1,RTRNRV ;POINTER TO "NORMAL" ROUTING VECTOR
ADDI P1,1 ;START WITH NODE ONE
SETZ T4, ;MAKE UP CHECKSUM IN THIS WORD
;Now put the hops and cost bytes for each node in the database in the
;message.
RTRSR2: LDB T1,[POINTR((P1),<RNHOP!RNCST>)] ;GET THE HOP!COST
ADD T4,T1 ;SUM THE CHECKSUM
CALL DNP2BY ;PLACE BYTES IN ROUTING MESSAGE
AOJ P1, ;LOOK AT NEXT ENTRY IN NRV
SOJG T3,RTRSR2 ;KEEP GOING OVER ALL ENTRIES
MOVE T1,T4 ;GET COPY OF CHECKSUM
CALL CKSNRM ;NORMALIZE THE CHECKSUM
CAME T1,RTRCKS ;IS IT THE SAME AS THE OLD CHECKSUM?
SKIPN RTRCKS ; AND DID WE HAVE ONE?
TRNA ;IT'S OK
BUG.(CHK,ROUBCD,ROUTER,SOFT,<Bad Checksum detected when building routing msg>,,<
Cause: This means that something got trashed. Look at P1, it point to the
end of the normal routing vector [RTRNRV]+[RTRMXN]. Look at the
vector itself (pointed to by RTRNRV) and see if the topology looks
reasonable. Look at RTRCKS and make sure it is less than 16 bits.
>,RTN)
MOVEM T1,RTRCKS ;STORE THE CHEKSUM
CALL DNP2BY ; AND WRITE IT IN MESSAGE
;Now we must make up the router header
XMOVEI T1,RM.MSD(MB) ;GET POINTER TO ROUTER'S MSD
CALL DNPINI ;SET UP TO WRITE HEADER
SETZ T1, ;BUILD FIRST BYTE IN T1
MOVX T2,XCT.RM ;TYPE = ROUTING MESSAGE
STOR T2,CMTYP,+T1 ;PLACE IT IN CORRECT FIELD
SETONE CMCTL,+T1 ;INDICATE IT IS A CONTROL MESSAGE
CALL DNP1BY ;PLACE THE BYTE
MOVE T1,RTRADR ;GET OUR ADDRESS
CALL DNP2BY ;PUT ADDRESS IN MESSAGE
XMOVEI T1,UD.MSD(MB) ;POINT TO USER DATA MSD
XMOVEI T2,RM.MSD(MB) ;MAKE RTR MSD POINT TO USER DATA MSD
SETZ T3, ;DON'T CHANGE BYTE POINTERS
CALL DNLMSS ;LINK IN THE MESSAGE SEGMENT
TRACE RTR,<Sending routing message>
INCR RCCMQ,(RC) ;INCREMENT NUMBER OF MESSAGES QUEUED
CALL CALQOB ;OUTPUT THE MESSAGE
SETZRO RCSRM,(RC) ;INDICATE WE HAVE SENT ROUTING MESSAGE
CALL DNGTIM ;GET THE CURRENT TIME
STOR T1,RCTLR,(RC) ;STORE IT IN CIRCUIT BLOCK AS TIME LAST SENT
; ROUTING MESSAGE
JRST RTRSR1 ;ALL DONE WITH THIS CIRCUIT, TRY NEXT ONE
SUBTTL RTRTMR - Routine to perform timer functions
;RTRTMR - Hello, Listener and other timer processes
;
; Call:
; RTRCBQ must point to the first circuit block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
;
;The hello process will periodically send a hello (test) message to a
;neighbor that has not sent us any messages in time T3. The listener process
;checks to see if a neighboring node has sent anything to us in time T4.
;If T4 expires, we declare the circuit down. Both T3 and T4 are checked based
;and RCTLM, which is the time that any sort of message was received from the
;neighbor.
RTRTMR: SKIPA RC,RTRCBQ ;GET THE FIRST CIRCUIT BLOCK
RTRTR1: LOAD RC,RCNXT,(RC) ;GET NEXT CIRCUIT BLOCK
JUMPE RC,RTN ;PUNT IF NO MORE
LOAD T4,RCSTA,(RC) ;GET THE STATE OF LINK
LOAD T1,RCNTY,(RC) ;GET THE NEIGHBOR'S NODE TYPE
CAIN T1,RCT.P2 ;IS IT A PHASE II?
JRST RTRTR1 ;YES, DON'T BOTHER SENDING OR LISTENING FOR
; HELLO/TEST MESSAGES
CAIE T4,RCS.TI ;IS LINK IN TI WAIT?
CAIN T4,RCS.TV ;IS IT IN TV WAIT?
TRNA ;YES, CHECK OUT TI TIMER
JRST RTRTR2 ;NO, CHECK OUT OTHER TIMERS
JE RCTIN,(RC),RTRTR2 ;IS INIT TIMER RUNNING?
CALL DNGTIM ;GET THE CURRENT TIME
OPSTR <SUB T1,>,RCTIN,(RC) ;SUBTRACT WHEN WE GOT THE PROTOCOL UP
CAMGE T1,RTRITM ;HAS TIME EXPIRED?
JRST RTRTR2 ;NO, JUST CONTINUE ON
;Here when the time allowed for the response to the TI we sent has expired.
ETRACE RTR,<Initialization timer expired and is restarting the circuit>
MOVX T1,RS.VRT ;EVENT REASON: VERIFICATION RECEIVE TIMEOUT
CALL RTEINL ;REPORT INITIALIZATION FAILURE EVENT
CALL RTRZCB ;CLEAN THE CIRCUIT BLOCK UP
CALL R2KINI ;INITIALIZE THE KONTROLLER
SETOM RTRRCF ;RECOMPUTE ROUTING LATER
JRST RTRTR1 ; AND TRY THE NEXT CIRCUIT
;Now check the hello and listener timers.
RTRTR2: CAIE T4,RCS.TT ;IS IT IN TEST?
CAIN T4,RCS.RN ;IS IT RUNNING?
TRNA ;YES, OK TO DO THINGS
JRST RTRTR1 ;NO, CHECK OUT THE NEXT CIRCUIT
CALL DNGTIM ;GET THE CURRENT TIME
OPSTR <SUB T1,>,RCTLM,(RC) ;SUBTRACT TIME OF LAST MESSAGE RECEIVED
OPSTR <CAMGE T1,>,RCTM4,(RC) ;DID THE LISTENER TIMER EXPIRE?
JRST RTRTR3 ;NO, CHECK THE HELLO TIMER
;Here when the listener timer has been exceeded. The circuit is declared
;down and re-initialization is tried.
ETRACE RTR,<Node listener timed out and is rejecting circuit>
MOVX T1,RS.ALT ;EVENT REASON: ADJACENT NODE LISTENER TIMEOUT
CALL RTELDL ;REPORT CIRCUIT DOWN - CIRCUIT FAULT EVENT
CALL RTRZCB ;CLEAR THE CIRCUIT BLOCK UP
CALL R2KINI ;TELL THE KONTROLLER TO INITIALIZE
SETOM RTRRCF ;RECOMPUTE ROUTING LATER
JRST RTRTR1 ; AND TRY THE NEXT CIRCUIT
;Check to see if the hello message timer has expired (T3) and if so,
;send out an hello message on the circuit.
RTRTR3: CALL DNGTIM ;GET THE CURRENT TIME
OPSTR <SUB T1,>,RCTLS,(RC) ;SUBTRACT BY THE TIME LAST MESSAGE WAS SENT
OPSTR <CAMGE T1,>,RCTM3,(RC) ;HAVE WE EXCEEDED THE HELLO TIMER?
JRST RTRTR1 ;NO, TRY THE NEXT CIRCUIT
;Build the data portion of the hello message.
MOVX T1,NO.HEL+1 ;LENGTH OF DATA SEGMENT
CALL DNGMSG ;GET THAT MANY BYTES
JRST RTRTR1 ;RESOURCE FAILURE, TRY NEXT TIME
MOVE MB,T1 ;SET UP MB WITH MESSAGE BLOCK POINTER
XMOVEI T1,UD.MSD(MB) ;INITIALIZE THE USER DATA SEGMENT
CALL DNPINI ;DO IT
MOVX T1,NO.HEL ;GET THE NUMBER OF HELLOS IN MESSAGE
CALL DNP1BY ;PLACE THE IMAGE COUNT IN THE MESSAGE
MOVX T3,NO.HEL ;GET THE COUNT FOR LOOP
RTRTR4: MOVX T1,HEL.LO ;WORD THAT GOES IN HELLO MESSSAGE
CALL DNP1BY ;PUT ONE IN
SOJG T3,RTRTR4 ; AND DO ANOTHER ONE IF NEEDED
;Make up the router header.
XMOVEI T1,RM.MSD(MB) ;POINT TO THE ROUTER PORTION OF MESSAGE
CALL DNPINI ;INITIALIZE IT
SETZ T1, ;BUILD THE BYTE IN T1
MOVX T2,XCT.TT ;TYPE OF CONTROL MESSAGE IS TEST MESSAGE
STOR T2,CMTYP,+T1 ;PUT IN BYTE
SETONE CMCTL,+T1 ;SAY IT'S A CONTROL MESSAGE
CALL DNP1BY ;PUT IN THE CTLFLG BYTE
MOVE T1,RTRADR ;GET OUR LOCAL ADDRESS
CALL DNP2BY ;PUT THE SOURCE ADDRESS IN MESSAGE
XMOVEI T1,UD.MSD(MB) ;LINK THE USER DATA
XMOVEI T2,RM.MSD(MB) ; TO THE ROUTER HEADER
SETZ T3, ;DON'T CHANGE ANY POINTERS
CALL DNLMSS ;LINK THEM
TRACE RTR,<Sending hello message>
INCR RCCMQ,(RC) ;INCREMENT NUMBER OF MESSAGES QUEUED
CALL CALQOB ;SEND THE MESSAGE
JRST RTRTR1 ; AND DO IT ALL AGAIN FOR THE NEXT CIRCUIT
SUBTTL Circuit Interface -- RTRDSP - Circuit Drivers Entry
;RTRDSP - Entry to Router from DLL
;
; Call:
; T1/ Function Code
; T2/ Router Circuit Block Address
; T3/ Data (ususally pointer to message block)
; T4/ More Data (used only with RTIOPN)
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
;
;We simply check the arguments, set up some arguments for the routines
;which handle the functions and dispatch to those routines.
;
;Note that we decide what to do if DECnet is not running at each
;individual interrupt handler. For example if DECnet is turned off
;between the buffer request and the input done, we could have problems.
;We do not accept and new buffer requests or protocol ups once DECnet
;has been turned off.
RTRDSP::CAXL T1,KI.PRU ;RANGE CHECK THE
CAXLE T1,KI.CLS ; FUNCTION CODE
BUG.(CHK,ROUILF,ROUTER,SOFT,<Illegal function code from Kontroller>,,<
Cause: This BUG is not documented yet.
>,RTN)
SEC1 ;DO OUR STUFF IN SECTION 1
SAVEAC <MB,MS,RC,P1,P2,T5,T6> ;SAVE SOME AC'S
MOVE T1,RTRDTB(T1) ;GET BITS AND DISPATCH FOR THIS FUNCTION.
TXZN T1,RD.CRC ;DID I GET AN RC?
JRST RTRDS2 ;NO
SKIPN RC,T2 ;USE RC TO HOLD CIRCUIT BLOCK ADDRESS
RTRDS1: BUG.(CHK,ROUBCB,ROUTER,SOFT,<Bad circuit block pointer>,,<
Cause: A Kontroller has called RTRDSP with a function requiring a circuit
block pointer and supplied a pointer (in t2) which failed the range
check.
Action: Find which Kontroller is supplying us with a bad circuit block pointer.
>,RTRDS9)
RTRDS2: TXZN T1,RD.CMB ;SHOULD I CHECK FOR A VALID MB?
JRST RTRDS4 ;NO, THIS FUNCTION DOESN'T HAVE AN MB.
SKIPN MB,T3 ;COPY THE MB
RTRDS3: BUG.(CHK,ROUBMB,ROUTER,SOFT,<Bad message block pointer>,,<
Cause: A Kontroller has called RTRDSP with a function requiring a message
block, and the pointer supplied (in T3) is either 0 or out of
range.
Action: Determine why the Kontroller gave us a bogus pointer (since he
originally should have obtained it from us).
>,RTRDS9)
IFN FTPARANOIA,<
CALL DNCHMB## ;ASK D36COM TO CHECK THIS POINTER FOR US
JRST RTRDS9 ;BAD POINTER, FORGET THIS REQUEST.
> ;END IFN FTPARANOIA
RTRDS4: TXZN T1,RD.CKS ;SHOULD WE CHECK DECNET/CIRCUIT STATE?
JRST RTRDS6 ;DON'T WORRY ABOUT STATE
SKIPN DCNSTA ;IS DECNET UP?
JRST RTRDS9 ;NO, RETURN NOW.
LOAD T2,RCSTA,(RC) ;GET THE CIRCUIT STATE
CAXE T2,RCS.OF ;IS THE CIRCUIT STATE OFF?
RTRDS6: CALLRET (T1) ;NO, CALL APPROPRIATE ROUTINE AND RETURN
ETRACE RTR,<RTRDSP called by circuit that should be dead>
RTRDS9: SETZ T1, ;MAKE SURE THAT THE REQUESTOR UNDERSTANDS
RET ; THAT THE REQUEST FAILED
RD.CRC==1B0 ;CHECK RC. MAKE SURE IT IS NON-ZERO, AND IF
; FTPARANOIA, RANGE CHECK AND FIND ON RTRCBQ
RD.CMB==1B1 ;CHECK MB. MAKE SURE IT IS NON-ZERO, AND IF
; FTPARANOIA, CALL DNCHFB TO ENSURE IT IS GOOD.
RD.CKS==1B2 ;CHECK STATES BEFORE CALLING. IF EITHER DECNET
; OR LINE STATE IS OFF, SIMPLY ZERO T1 AND
; RETURN.
RTRDTB: RD.CRC+RD.CKS+RTIPRU ;PROTOCOL "UP"
RD.CRC+RD.CKS+RTIDWN ;PROTOCOL "DOWN"
RD.CRC+RD.CKS+RTIMMR ;MAINT MESSAGE RECEIVED
RD.CRC+RD.CKS+RTISMR ;START MESSAGE RECEIVED
RD.CRC+RD.CMB+RTIOTC ;OUTPUT COMPLETE
RD.CRC+RD.CMB+RTIOTI ;OUTPUT INCOMPLETE
RD.CRC+RD.CMB+RTIINC ;INPUT COMPLETE
RD.CRC+RD.CKS+RTIBRQ ;BUFFER REQUEST
RTIOPN ;OPEN CIRCUIT
RD.CRC+ RTICLS ;CLOSE CIRCUIT
SUBTTL Circuit Interface -- RTIOPN - Open a new circuit
;RTIOPN - Open a new circuit
;
; Call:
; T3/ Kontroller Block Address
; T4/ Line-ID
;
; Return:
; RET ;ALWAYS, RETURNS WITH T1 CONTAINING CIRCUIT
; ; BLOCK ADDRESS OR ZERO IF IT COULDN'T
; ; ALLOCATE A NEW ONE
;
; Uses: T1-T4
;
;Note that this call has a different format that the other kontroller
;interrupt calls. Since we don't have a circuit block address yet,
;T2 doesn't mean anything.
RTIOPN: DMOVE P1,T3 ;SAVE KBA AND LINE-ID
MOVE T1,P2 ;GET THE LINE-ID
CALL RTRGCB ;FIND THE MATCHING CIRCUIT BLOCK
TRNA ;NO CIRCUIT BLOCK, CREATE IT
JRST RTIOP1 ;WE HAVE A CIRCUIT BLOCK, TRY TO SET THE STATE
CALL RTRMCB ;MAKE UP THE CIRCUIT BLOCK
JRST [ SETZ T1, ;RETURN NO CIRCUIT-BLOCK PTR
RET] ; AND RETURN
MOVE RC,T1 ;CIRCUIT BLOCK POINTER WE GOT.
ENDQUE RC,RTRCBQ,RC.NXT,T1 ;ADD CIRCUIT BLOCK TO LIST
RTIOP1: STOR P1,RCKBA,(RC) ;STORE THE KONTROLLER DISPATCH ADDRESS
STOR P2,RCLID,(RC) ; AND THE LINE-ID
MOVX T1,RCS.WT ;PUT INTO WAIT STATE TO
STOR T1,RCSTA,(RC) ; TO BEGIN WITH
MOVE T1,RC ;RETURN PTR TO NEW CKT-BLK TO KONTROLLER
RET ; AND RETURN TO SENDER
SUBTTL Circuit Interface -- RTICLS - Close a Circuit
;RTICLS - Close a Circuit
;
; Call:
; RC/ Circuit Block Pointer
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T2
;
;Note that we don't free the circuit block. We simply clear portions of
;the block out and declare it down. If we later get a OPN from a
;kontroller which gives the same line-id, we will use the block again.
RTICLS: CALL RTRZCB ;ZERO IMPORTANT PARTS OF THE BLOCK
MOVX T1,RCS.OF ;DECLARE IT AS
STOR T1,RCSTA,(RC) ; DOWN
RET ; AND RETURN (THAT WAS EASY)
SUBTTL Circuit Interface -- RTIPRU - Process Protocol Up
;RTIPRU - Handle the "protocol up" interrupt from the kontroller
;
; Call:
; RC/ Circuit block address
; T2/ State of circuit
;
; Return:
; RET ;ALWAYS
;
; Uses:
RTIPRU: TRACE RTR,<Received "protocol-up" from kontroller>
LOAD T2,RCSTA,(RC) ;GET CIRCUIT STATE
CAIE T2,RCS.WT ;MAKE SURE WE'RE IN WAITING STATE
JRST [ETRACE RTR,<Protocol Up rcvd in wrong state>
CALLRET R2KINI] ;TRY TO REINITIALIZE THE CIRCUIT
MOVX T1,RCS.TI ;NEW STATE = TRANSPORT INITIALIZATION WAIT
STOR T1,RCSTA,(RC) ;STORE THE NEW CIRCUIT STATE
MOVX T1,TI.MXL ;MAX LENGTH OF A TI MESSAGE
CALL DNGMSG ; USER MESSAGE AREA
CALLRET R2KINI ;CAN'T DO IT, GO INTO INI STATE
MOVE MB,T1 ;MAKE MB POINT TO MESSAGE
XMOVEI T1,UD.MSD(MB) ;POINT TO THE USER-DATA MSD
CALL DNPINI ;INITIALIZE MS & THE MSD
SETZ T1, ;MAKE UP FIRST BYTE IN T1/ 0
SETONE CMCTL,+T1 ;TURN ON THE CONTROL MESSAGE BIT
MOVX T2,XCT.TI ;TYPE IS ROUTER INIT
STOR T2,CMTYP,+T1 ;AND STORE THAT IN THE TYPE FIELD
CALL DNP1BY ;WRITE THE FIRST BYTE
MOVE T1,RTRADR ;GET OUR ADDRESS
CALL DNP2BY ;STORE THE NODE ADDRESS
;Build TLINFO.
SETZ T1, ;START BUILDING TLINFO FIELD
MOVX T2,RNT.RT ;WE ARE A ROUTING NODE
STOR T2,TINTY,+T1 ;STORE THE NODE TYPE
TMNE RCVRQ,(RC) ;IS VERIFICATION REQUIRED?
TXO T1,TIVER ;YES, TELL HIM ABOUT IT
CALL DNP1BY ;PUT THE BYTE IN
;Give him the useless blocksize.
MOVE T1,RTRBSZ ;GET THE BLOCKSIZE (USELESS)
CALL DNP2BY ; AND TELL HIM NOTHING
;Fill in version, etc.
MOVE T1,RTRVER ;VERSION OF RTR
CALL DNP1BY ;PUT IT IN MESSAGE
MOVE T1,RTRECO ;EDIT NUMBER OF RTR
CALL DNP1BY ;PUT IT IN, ALSO
MOVE T1,RTRCUS ;CUSTOMER ARGUMENT NUMBER
CALL DNP1BY ;AND STORE THAT ALSO
;Now fill in one reserved byte (supposedly a image count)
SETZ T1, ;USE A ZERO
CALL DNP1BY ;PUT IN THE BYTE
;Here we give the message to the DLL to send.
TRACE RTR,<Sending Router Init message>
INCR RCCMQ,(RC) ;INCREMENT NUMBER OF MESSAGES QUEUED
CALL CALQOB ;OUTPUT THE MESSAGE
CALL DNGTIM ;GET THE CURRENT TIME
STOR T1,RCTIN,(RC) ;REGISTER THE TIME THAT WE SENT THE TI
RET ;RETURN TO SENDER
SUBTTL Circuit Interface -- RTIDWN - Process Protocol Down
;RTIDWN - Routine to process a protocol down interrupt
;
; Call:
; RC/ Circuit block address
;
; Return:
; RET ;ALWAYS
;
; Uses: T1
RTIDWN: TRACE RTR,<Received "protocol-down" from DLL>
MOVX T1,RS.LSL ;EVENT REASON: CIRCUIT SYNCHRONIZATION LOST
CALL RTELDL ;REPORT CIRCUIT DOWN - CIRCUIT FAULT EVENT
CALL RTRZCB ;CLEAN OUT THE CIRCUIT BLOCK
MOVX T1,RCS.WT ;GET "WAIT" STATE CODE
STOR T1,RCSTA,(RC) ;STORE AS CURRENT STATE FOR THIS CIRCUIT
SETOM RTRRCF ;FLAG RTRRCR TO BE CALLED NEXT TIC
RET
SUBTTL Circuit Interface -- RTIMMR - Process Maintainence Message
;RTIMMR - Routine to process a recieved maintanence message
;
; Call:
; RC/ Circuit block address
;
; Return:
; RET ;ALWAYS
;
; Uses: T1
RTIMMR: TRACE RTR,<Received maintainance message>
MOVX T1,RS.LSL ;EVENT REASON: CIRCUIT SYNCHRONIZATION LOST
CALL RTELDL ;REPORT CIRCUIT DOWN - CIRCUIT FAULT EVENT
CALL RTRZCB ;CLEAN UP CIRCUIT BLOCK
CALL R2KHLT ;HALT THE CIRCUIT
BUG.(INF,ROUMMR,ROUTER,SOFT,<Maintainence Message recieved>,,<
Cause: This BUG is not documented yet.
>)
SETOM RTRRCF ;FLAG FOR RTRRCR TO RUN
RET ;AND RETURN
SUBTTL Circuit Interface -- RTISMR - Process Start Message
;RTISMR - Routine to process a recieved start message
;
; Call:
; RC/ Circuit block address
;
; Return:
; RET ;ALWAYS
;
; Uses: T1
RTISMR: TRACE RTR,<Start message received>
MOVX T1,RS.LSL ;EVENT REASON: CIRCUIT SYNCHRONIZATION LOST
CALL RTELDL ;REPORT CIRCUIT DOWN - CIRCUIT FAULT EVENT
CALL RTRZCB ;CLEAN UP CIRCUIT BLOCK
CALL R2KHLT ;HALT THE CIRCUIT
BUG.(INF,ROUSMR,ROUTER,SOFT,<Start Message recieved>,,<
Cause: This BUG is not documented yet.
>)
SETOM RTRRCF ;FLAG FOR RTRRCR TO BE CALLED NEXT TIC
RET
SUBTTL Circuit Interface -- RTIBRQ - Process the Buffer Request
;RTIBRQ - Process the input buffer request
;
; Call:
; RC/ Circuit Block Address
; T3/ Length of Buffer wanted
;
; Return:
; RET ;ALWAYS WITH T1 POINTING TO MESSAGE BLOCK
; ; OR T1 SET TO ZERO ON ALLOCATION FAILURE
;
; Uses: T1-T3
RTIBRQ: TRACE RTR,<Recieved buffer request from DLL>
MOVE P1,T3 ;SAVE THE SIZE OF MSG WANTED IN BYTES
CAMLE P1,RTRBSZ ;IS BUFFER WITHIN OUR RANGE?
JRST [LOAD T2,RCLID,(RC) ;GET THE ENTITY ID (FOR CIRCUIT)
EVENT RE.OPL,<Oversized packet loss event>
AOS RTRCOP ;INCREMENT THE OVERSIZED PACKET COUNTER
MOVE P1,RTRBSZ ;USE MAX BUFFER SIZE
SETZ T1, ;GIVE ALLOCATION FAILURE TO DLL
RET] ; AND RETURN
MOVE T1,P1 ;SET UP ARG TO DNGMSG
CALL DNGMSG ;GET THE MESSAGE BLOCK WITH T1 BYTES OF USER
; DATA AREA
CALL RTIBR1 ;COULDN'T ALLOCATE USE EMERGENCY BUFFER
JUMPE T1,RTN ;JUST RETURN IF WE'RE STARVING THE DLL
XMOVEI T2,IN.MSD(T1) ;POINT TO THE INPUT MSD
STOR T2,MBFMS,(T1) ;STORE IN FIRST MSD SLOT
RET ;TO SENDER
;Here when we couldn't get a buffer from the memory manager. If our neighbor
;isn't a Phase II node, use the per-circuit emergency buffer, in case it's a
;important control message. Otherwise, return a zero in T1 for the DLL.
RTIBR1: SETZ T1, ;START OFF WITH NOTHING FOR THE DLL
LOAD T2,RCNTY,(RC) ;GET THE NEIGHBORING NODE'S TYPE
CAIN T2,RCT.P2 ;A REAL PHASE II NODE?
RET ;GIVE DLL ZERO TO INDICATE RESOURCE FAILURE
TMNE RCEBU,(RC) ;IS THE BUFFER IN USE?
BUG.(CHK,ROUEBI,ROUTER,SOFT,<Emergency circuit buffer already in use>,,<
Cause: This BUG is not documented yet.
>,RTN)
;USE IT ANYWAY
MOVE T1,P1 ;GET THE LENGTH TO USE
CALL DNGEMS ;GET ONE OF THE EMERGENCY MESSAGE BLOCKS
BUG.(CHK,ROUDGE,ROUTER,SOFT,<Didn't get reserved emergency msg blk>,,<
Cause: We should never run out of emergency blocks, ROUTER should
sign up for enough blocks and then use no more than signed up for.
Cure: Either ROUTER hasn't signed up for enough emergency blocks or
has used too many. If too many, they are probably in some
input queue. Find all calls to DNGEMS and DNMINP and find who
used too many.
>,RTN)
XMOVEI T2,IN.MSD(T1) ;POINT TO THE INPUT MSD
STOR T2,MBFMS,(T1) ;STORE IN FIRST MSD SLOT
SETONE RCEBU,(RC) ;SET THE INUSE BIT FOR THIS CIRCUIT
RET ; AND RETURN WITH T1 POINTING TO EMERGENCY AREA
SUBTTL Circuit Interface -- RTIOTC - Process Output Complete
;RTIOTC - Routine to process output complete interrupt
;
; Call:
; RC/ Circuit block address
; T3/ Message block address
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T3
RTIOTC: TRACE RTR,<Output Complete>
MOVE MB,T3 ;GET THE MESSAGE BLOCK ADDRESS
MOVE T1,MB ;ARG FOR DNLENG
CALL DNLENG ;FIGURE OUT THE LENGTH OF THE MESSAGE
OPSTRM <ADDM T1,>,RCBYS,(RC) ;UPDATE BYTES SENT
INCR RCDBS,(RC) ;INCREMENT THE NUMBER OF BLOCKS SENT
DECR RCCMQ,(RC) ;DECREMENT MESSAGES QUEUED COUNT
CALL DNGTIM ;GET CURRENT TIME
STOR T1,RCTLS,(RC) ;SAVE AS TIME LAST MESSAGE SENT
JN RMCTL,(MB),FREMSG ;IF IT'S A CONTROL MESSAGE, JUST
; FREE THE MESSAGE
JN RMICP,(MB),[INCR RCCTS,(RC) ;IF THE MESSAGE IS NOT FROM A LOCAL
CALLRET FREMSG] ; NODE, INCREMENT THE TRANSIT COUNT
; AND DISCARD THE PACKET
INCR RCCLC,(RC) ;OTHERWISE, INCREMENT THE LOCAL COUNT
CALLRET FREMSG ;GIVE PACKET TO BACK TO NSP, OR FREE IT
SUBTTL Circuit Interface -- RTIOTI - Process Output Incomplete
;RTIOTI - Process the output incomplete interrupt
;
; Call:
; RC/ Pointer to circuit block
; T3/ Pointer to message block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T3
RTIOTI: TRACE RTR,<Output not done>
CALLRET RTIOTC ;JUST CALL OUTPUT COMPLETE
SUBTTL Circuit Interface -- RTIINC - Process Input Complete
;RTIINC - Process input complete interrupt
;
; Call:
; RC/ Circuit block pointer
; T3/ Pointer to message block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T3
RTIINC: TRACE RTR,<Input Complete>
MOVE MB,T3 ;GET POINTER TO MESSAGE BLOCK
RTRITR:: ;LABEL FOR DNSNUP TO FIND INPUT MESSAGES
STOR RC,RMICP,(MB) ;STORE THE INPUT CIRCUIT ADDRESS
MOVE T1,MB ;COPY POINTER TO MESSAGE BLOCK
CALL DNLENG ;SIZE OF THIS MESSAGE
OPSTRM <ADDM T1,>,RCBYR,(RC) ;UPDATE TOTAL BYTES RECEIVED
INCR RCDBR,(RC) ;INCREMENT TOTAL DATA BLOCKS RECEIVED
CALL DNGTIM ;GET THE CURRENT TIME
STOR T1,RCTLM,(RC) ;STORE TIME WE LAST HEARD FOR NEIGHBOR
CALL RTRHDP ;PARSE THE HEADER
CALLRET RTEMFE ;REPORT THE MESSAGE FORMAT ERROR EVENT
JN RMPH2,(MB),RTRPH2 ;IF IT'S A PHASE II MESSAGE, PROCESS IT
JE RMCTL,(MB),RTIIN1 ;IF IT'S A DATA MESSAGE, PROCESS IT
;We have a control message here, find the type and dispatch
LOAD T1,RCSTA,(RC) ;GET THE CIRCUIT'S STATE
LOAD T2,RMCTY,(MB) ;GET THE CONTROL MESSAGE TYPE
CALL @RTIIND(T2) ; AND DISPATCH ON THAT TYPE
SETZRO RCEBU,(RC) ;EMERGENCY BUFFER IS NO LONGER IN USE
RET ;RETURN TO SENDER
RTIIND: IFIW RTCINI ;ROUTER INITIALIZATION (0)
IFIW RTCVER ;ROUTER VERIFICATION (1)
IFIW RTCTST ;ROUTER TEST MESSAGE (2)
IFIW RTCRTE ;ROUTER ROUTING MESSAGE (3)
;Here with a data message.
RTIIN1: TMNE MBEBF,(MB) ;IS THIS MESSAGE IN AN EMERGENCY BUFFER?
JRST RTIINE ;YES, HANDLE IT DIFFERENTLY
RTIIN2: LOAD T1,RCSTA,(RC) ;GET THE STATE OF THE CIRCUIT
CAIE T1,RCS.TT ;SEE IF THIS IS A GOOD STATE TO BE IN
CAIN T1,RCS.RN ; FOR RECIEVING DATA
TRNA ;WE SEEM TO BE OK
JRST [ETRACE RTR,<Circuit in wrong state for forwarding>
CALLRET FREMSG]
CALLRET RTRFWD ;FORWARD THE MESSAGE
;At this point we have a data message in an emergency buffer. If it is
;from a Phase II node, we cannot throw the message away. We therefore
;check the node type vector to see if the source was a Phase II node,
;and if it was we forward the message normally.
RTIINE: LOAD T1,MBSRC,(MB) ;YES, LET'S CHECK IF
CALL RTNRNT ; FROM A PHASE II NODE
CAIE T1,NTV.P2 ;IS IT PHASE II?
JRST RTIINF ;NO, WE MUST PUNT MESSAGE
SETONE MBPH2,(MB) ;YES, CALL IT A PHASE2 MESSAGE
JRST RTIIN2 ; AND FORWARD IT NORMALLY, AS WE
;ARE NOT ALLOWED TO PUNT PHASE II
;MESSAGES
;Here to discard an arriving phase III packet due to congestion.
RTIINF: OPSTR <SKIPL T2,>,MBDST,(MB) ;GET THE DESTINATION
CAMLE T2,RTRMXN ;RANGE CHECK IT
CALLRET RTRFOR ;DESTINATION IS OUT-OF-RANGE
ADD T2,RTRNRV ;GET THE NODE'S ROUTING VECTOR ENTRY
JE RNLCL,(T2),[INCR RCCAL,(RC) ;IF IT WAS SUPPOSED TO COME TO US
JRST RTIIN3] ;REPORT IT AS ARRIVIED CONGESTION LOSS
INCR RCCTL,(RC) ;INCREMENT THE TRANSIT CONGESTION LOSS
RTIIN3: SETZRO RCEBU,(RC) ;EBUF ALLOCATED TO CIRCUIT NO LONGER IN USE
;COULDN'T DO IT, LETS PUNT THE MESSAGE
CALLRET FREMSG ;FREE MSG BLK & RETURN
SUBTTL Control Message Processors -- RTCINI - Init Messages
;RTCINI - Process Incoming Router Init Message
;
; Call:
; T1/ Circuit State
; RC/ Ptr to Circuit Block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
RTCINI: TRACE RTR,<Processing Router Init message>
CAIE T1,RCS.TI ;ARE WE IN RTR INIT WAIT STATE?
JRST [ETRACE RTR,<RTR Init message rcvd in wrong state>
MOVX T1,RS.UPT ;EVENT REASON: UNEXPECTED PACKET LOSS
CALLRET RTELDS] ;REPORT THE CIRCUIT DOWN - SOFTWARE FAULT EVENT
LOAD T1,MBSRC,(MB) ;GET THE SOURCE NODE
CAIL T1,1 ;CHECK NODE ADDRESS
CAMLE T1,RTRMXN ; FOR REASONABLENESS
JRST [MOVX T1,RS.ANO ;REASON: ADJACENT NODE ADDRESS OUT OF RANGE
CALLRET RTEINO] ;REPORT THE INITIALIZATION FAILURE EVENT
STOR T1,RCNAD,(RC) ;STORE IT
MOVE T1,MB ;POINT TO INPUT MESSAGE
CALL DNLENG ;CALCULATE THE LENGTH
CAIGE T1,^D6 ;IS IT THE CORRECT LENGTH FOR RTR INIT MSGS?
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
;Check the first byte of the init message (TLINFO)
CALL DNG1BY ;GET THE INITINFO FIELD
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR
TXNE T1,TIRSV ;IS THE RESERVED FIELD ZERO?
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
MOVX T2,RCVRQ ;GET THE VERFIFY REQUIRED BIT
ANDCAM T2,RC.VRQ(RC) ;ASSUME THAT VERIFICATION ISN'T REQUIRED
TXNE T1,TIVER ;IS IT REALLY REQUIRED?
IORM T2,RC.VRQ(RC) ;YES, SET IT
LOAD T2,TINTY,+T1 ;GET NODE TYPE FROM BYTE
SETZ T1, ;USE T1 TO HOLD NODE TYPE FOR CIRCUIT BLOCK
CAIN T2,RNT.RT ;IS IT A ROUTING NODE?
MOVX T1,RCT.3F ;YUP, MUST BE A PHASE III FULL NODE
CAIN T2,RNT.NR ;IS IT A NON-ROUTING NODE?
MOVX T1,RCT.3S ;YES, WELL ITS A PHASE III END NODE
SKIPN T1 ;DID WE GET ONE?
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCNTY,(RC) ;STORE THE NODE TYPE IN CIRCUIT BLOCK
;Get the blocksize (which is quite useless).
CALL DNG2BY ;GET TWO BYTES OF GARBAGE
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
; CAMGE T1,RTRBSZ ;IS THE BLOCKSIZE REASONABLE
; JRST [MOVX T1,RS.VSK ;EVENT REASON: VERSION SKEW
; CALLRET RTEINO] ;REPORT THE INITIALIZATION FAILURE EVENT
STOR T1,RCBSZ,(RC) ; AND STORE IT FOR WHATEVER REASON
;Next comes the Version number, ECO number and Customer args.
CALL DNG1BY ;GET THE VERSION NUMBER
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCVER,(RC) ;STORE IN IN CIRCUIT BLOCK
CALL DNG1BY ;GET THE ECO NUMBER
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCECO,(RC) ;STORE IT
CALL DNG1BY ;ALSO THE CUSTOMER ARGUMENT
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCCUS,(RC) ;STORE IT ALSO
;Now we have read the whole message, next send a verification if necessary.
TMNE RCVRQ,(RC) ;DOES HE WANT VERIFICATION?
JRST RTCIN1 ;YES.
MOVX T1,RCS.TV ;ASSUME THAT WE REQUIRE VERIFICATION
SKIPN RTRVRQ ;DO WE REQUIRE VERIFICATION?
MOVX T1,RCS.RN ;NO, WE'RE NOW IN RUN STATE
STOR T1,RCSTA,(RC) ;INDICATE THAT IN THE CIRCUIT BLOCK
CAXN T1,RCS.RN ;DID WE END UP IN RUN STATE?
CALL RTELUP ;YES, SIGNAL CIRCUIT UP EVENT
SETOM RTRRCF ;FLAG THE NEED FOR A TOPOLOGY RECOMPUTE
SETZRO RCTIN,(RC) ;ZERO THE TIME WE SENT TI TIMER
CALLRET FREMSG ; FREE MESSAGE AND RETURN
RTCIN1: MOVE T1,MB ;PASS PTR TO MSG BLK TO DNMINI
SETZ T2, ;ZERO LENGTH USER DATA SPACE FOR PSWD
CALL DNMINI ;FIX UP THE MSG BLK
RET ;PROPOGATE ERROR RETURN
XMOVEI T1,RM.MSD(MB) ;GET ADDR OF ROUTER MSD
CALL DNPINI ;GET READY TO STICK BYTES IN MESSAGE
SETZ T1, ;BUILD FIRST BYTE IN T1
MOVX T2,XCT.TV ;TYPE = ROUTER VERIFICATION
STOR T2,CMTYP,+T1 ;FILL IN FIELD IN AC
SETONE CMCTL,+T1 ;TV MESSAGE IS A CONTROL MESSAGE
CALL DNP1BY ;STORE IN MESSAGE
MOVE T1,RTRADR ;GET OUR (ROUTER'S) ADDRESS
CALL DNP2BY ;STORE THAT
;Put a zero length password at the end of the verification msg
SETZ T1, ;MAKE A ZERO COUNT FIELD
CALL DNP1BY ;TELL MSG ABOUT IT
TRACE RTR,<Sending Router Verification message>
INCR RCCMQ,(RC) ;INCREMENT NUMBER OF MESSAGES QUEUED
CALL CALQOB ;OUTPUT THE MESSAGE.
CALL DNGTIM ;GET CURRENT TIME
STOR T1,RCTIN,(RC) ;REGISTER THE TIME THAT WE SENT THE TV
MOVX T1,RCS.TV ;ASSUME THAT WE REQUIRE VERIFICATION
SKIPN RTRVRQ ;DO WE REQUIRE VERIFICATION?
MOVX T1,RCS.RN ;NO, WE'RE NOW IN RUN STATE
STOR T1,RCSTA,(RC) ;INDICATE THAT IN THE CIRCUIT BLOCK
CALLRET RTELUP ;SIGNAL CIRCUIT UP EVENT AND RETURN
SUBTTL Control Message Processors -- RTCVER - Verification Messages
;RTCVER - Routine to handle verification messages
;
; Call:
; T1/ Circuit State
; RC/ Pointer to Circuit Block
; MB/ Pointer to Message Block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
RTCVER: TRACE RTR,<Processing Router Verification message>
SAVEAC <P1,P2> ;SAVE 2 PEAS
CAIE T1,RCS.TV ;ARE WE WAITING FOR A VERIFICATION
JRST [ETRACE RTR,<RTR Verification message rcvd in wrong state>
MOVX T1,RS.UPT ;EVENT REASON: UNEXPECTED PACKET
CALLRET RTELDS] ;REPORT CIRCUIT DOWN - SOFTWARE ERROR EVENT
CALL DNG1BY ;GET FIRST BYTE (IMAGE COUNT)
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
MOVE P1,T1 ;PRESERVE IT FOR A WHILE
MOVE T1,MB ;POINT TO MESSAGE
CALL DNLENG ;CALCULATE LENGTH
CAMLE P1,T1 ;DOES IT LOOK LIKE A REASONABLE LENGTH?
CALLRET RTEVRJ ;++VERIFICATION REJECT
MOVX T1,RCS.RN ;IF WE GOT THIS FAR,
STOR T1,RCSTA,(RC) ; WE DESERVE TO BE IN A GOOD STATE
CALL RTELUP ;SIGNAL CIRCUIT UP EVENT
CALLRET FREMSG ;TOSS MESSAGE AND RETURN
SUBTTL Control Message Processors -- RTCRTE - Routing Messages
;RTCRTE - Routine to handle incoming routing message
;
; Call:
; T1/ State of circuit
; RC/ Pointer to circuit block
; MB/ Poiner to message block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
RTCRTE: TRACE RTR,<Processing Routing message>
CAIE T1,RCS.TT ;CHECK OUR STATE FOR EITHER TEST OR
CAIN T1,RCS.RN ; OK STATE
TRNA ;WE SEEM ALRIGHT
JRST [ETRACE RTR,<Routing message rcvd in wrong state>
MOVX T1,RS.UPT ;EVENT REASON: UNEXPECTED PACKET RECEIVED
CALLRET RTELDS] ;REPORT CIRCUIT DOWN - SOFTWARE FAULT EVENT
LOAD T1,MBSRC,(MB) ;GET THE SOURCE ADDRESS
OPSTR <CAME T1,>,RCNAD,(RC) ;IS THAT THE ADDRESS WE EXPECTED?
JRST [MOVX T1,RS.ANA ;EVENT REASON: ADJACENT NODE ADDRESS CHANGE
CALLRET RTELDO] ;REPORT CIRCUIT DOWN - OPERATOR FAULT EVENT
MOVE T1,MB ;POINT TO INPUT MESSAGE
CALL DNLENG ;GET ITS LENGTH
TXNE T1,1B35 ;SEE IF IT'S AN EVEN LENGTH
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
SUBI T1,2 ;GET COUNT WITHOUT CHECKSUM
ASH T1,-1 ;MAKE IT ENTRY COUNT
SKIPLE T1 ;RANGE CHECK THE LENGTH
CAMLE T1,RTRMXN ; OF THE MESSAGE
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CAME T1,RTRMXN ;IT'S A ROUTING UPDATE LOSS IF MESSAGE ISN'T
; EXACTLY THE LENGTH THAT WE ARE EXPECTING
CALL RTCRTF ; SO REPORT THE LOSS AND COME BACK
MOVE T4,T1 ;GET COPY OF ENTRY COUNT
CALL DNRPOS ;READ THE POSTION IN MESSAGE
STOR T1,RMMK2,(MB) ;STORE THE ROUTING MESSAGE POSITION
;Here to read the message, while summing the checksum.
SETZ T3, ;A PLACE FOR THE CHECKSUM
RTCRT1: CALL DNG2BY ;GET A BYTE OF THE ROUTING MESSAGE
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
ADD T3,T1 ;SUM THE CHECKSUM
SOJG T4,RTCRT1 ;SKIM THROUGH IT
;Get the checksum in the message and verify it.
CALL DNG2BY ;GET THE CHECKSUM FROM THE MESSAGE
JRST [MOVX T1,RS.RUC ;EVENT ERROR: CHECKSUM ERROR DETECTED
CALLRET RTELDS] ;REPORT THE CIRCUIT DOWN - SOFTWARE ERROR EVENT
EXCH T1,T3 ;EXCHANGE THE CHECKSUMS
CALL CKSNRM ;NORMALIZE THE ONE WE FIGURED OUT
CAME T1,T3 ;BETTER BE THE SAME
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
;Free the old message and link in the new one.
LOAD T1,RCLRM,(RC) ;GET POINTER TO LAST ROUTING MESSAGE SENT
STOR MB,RCLRM,(RC) ;STORE THIS MESSAGE THAT WE GOT
JUMPE T1,RTCRT3 ;IF NONE THERE, DON'T TRY TO FREE IT
TMNE MBEBF,(MB) ;IS THIS MESSAGE IN AN EMERGENCY BUFFER?
JRST RTCRT2 ;NO, JUST FREE IT UP NORMALLY
SETONE MBEBF,(T1) ;MAKE OLD MESSAGE INTO A "EMERGENCY" BUFFER
SETZRO MBEBF,(MB) ; AND MAKE THE NEW ONE A REGULAR BUFFER
RTCRT2: CALL DNFMSG ; FREE IT UP
RTCRT3: SETOM RTRRCF ;LET PEOPLE KNOW WE HAVE TO RECOMPUTE TOPOLOGY
RET ;TO SENDER
;Here to report the partial routing update loss.
RTCRTF: SAVEAC <T1,T2,T3,T4> ;WE'RE RELYING ON THESE ACS
MOVE T3,T1 ;SET UP THE NODE NUMBER
LOAD T2,RCLID,(RC) ;GET THE ENTITY ID
EVENT RE.PRL,<Partial routing update loss event>,MB
AOS RTRCPR ;INCREMENT THE COUNTER
RET ;RETURN
SUBTTL Control Message Processors -- RTCTST - Test or Hello Messages
;RTCTST - Routine to handle the hello and test messages
;
; Call:
; T1/ State of Circuit
; RC/ Pointer to Circuit Block
; MB/ Pointer to Message Block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
;
;Router Hello and Test messages consist of a image count followed by that
;count of bytes filled with some constant (HEL.LO).
RTCTST: TRACE RTR,<Processing test or hello message>
CAIE T1,RCS.TT ;ARE WE IN TEST OR
CAIN T1,RCS.RN ; OK MODE?
TRNA ;YES
JRST [ETRACE RTR,<Test or Hello message rcvd in wrong state>
MOVX T1,RS.UPT ;REASON: UNEXPECTED PACKET RECEIVED
CALLRET RTELDS] ;REPORT CIRCUIT DOWN - CIRCUIT FAULT EVENT
LOAD T1,MBSRC,(MB) ;GET THE SOURCE ADDRESS
OPSTR <CAME T1,>,RCNAD,(RC) ;IS IT WHAT WE EXPECTED?
JRST [MOVX T1,RS.ANA ;REASON: ADJACENT NODE ADDRESS CHANGED
CALLRET RTELDO] ;REPORT CIRCUIT DOWN - OPERATOR FAULT EVENT
CALL DNG1BY ;GET THE IMAGE COUNT OF TEST MESSAGE
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CAILE T1,^D128 ;IS THE LENGTH WITHIN REASON
BUG.(INF,ROUBTF,ROUTER,SOFT,<Bad Test message format>,,<
Cause: This BUG is not documented yet.
>,FREMSG)
;Check to see if the test data is ok.
MOVE T4,T1 ;PRESERVE IT SORT OF
SOJGE T4,[CALL DNG1BY ;GET A BYTE OF THE TEST
JRST [MOVX T1,RS.ALI ;REASON: INVALID TEST DATA
CALLRET RTELDS] ;REPORT THE CIRCUIT DOWN EVENT
CAIE T1,HEL.LO ;IS IT EQUAL TO THE MAGIC NUMBER
BUG.(INF,ROUBTM,ROUTER,SOFT,<Bad Hello or Test message>,,<
Cause: This BUG is not documented yet.
>,FREMSG)
JRST .] ;LOOK AT ALL THE BYTES
CALLRET FREMSG ;FREE THE MESSAGE AND RETURN
SUBTTL RTRHDP - Parse a Input Router Message Header
;RTRHDP - Parse Router Header on Incoming Message
;
; Call:
; MB/ Pointer to Input message
;
; Return:
; RET ;IF BAD HEADER
; RETSKP ;ON SUCCESS
;
; Uses: T1-T2
;
;Note that DNGINI is called here and should not be recalled afterwards
;for the Router MSD.
RTRHDP: MOVE T1,MB ;POINT TO THE MESSAGE BLOCK
CALL DNGINI ;SET UP FOR CALLS TO DNGXBY
CALL DNRPOS ;GET OUR POSITION
STOR T1,RMMK1,(MB) ;STORE IT FOR EVENT PROCESSING
CALL DNG1BY ;GET THE FIRST BYTE
RET ;RAN OUT, GIVE ERROR RETURN
STOR T1,RMFST,(MB) ;STORE IT FOR PEOPLE TO USE
TXNE T1,RM%EVL ;IS THE EVOLUTION BIT SET?
JRST RTRHD1 ;YES, IT HAS A PHASE II ROUTING HEADER
TXNE T1,RM%CTL ;IS THIS A CONTROL MESSAGE?
JRST RTRHDC ;YES, GO HANDLE IT
;Check all the fields in the packet route header and store pertinent fields
;in the message block.
TXNN T1,RM%MB1 ;IF LOW TWO ORDER BYTES ARE 00, THIS
; MESSAGE IS A PHASE II WITHOUT A ROUTING
; HEADER
JRST RTRHD1 ;IT IS, RETURN, INDICATING PHASE II MESSAGE
TXNE T1,RM%MZ1!RM%MZ2!RM%ALM ;MAKE SURE THESE FIELDS ARE ZERO
RET ;THEY'RE NOT, GIVE ERROR RETURN
TXNE T1,RM%RQR ;IS RQR ON?
TXNN T1,RM%RTS ; AND RTS
TRNA ;NO, OK
RET ;YES, THAT'S A PROBLEM
;Now parse the source, destination and visits fields of packet route header.
CALL DNG2BY ;GET THE DESTINATION ADDRESS
RET ;OUT OF BYTES, GIVE BAD RETURN
STOR T1,MBDST,(MB) ;STORE IT
CALL DNG2BY ;GET THE SOURCE ADDRESS
RET ;RAN OUT, GIVE BAD RETURN
STOR T1,MBSRC,(MB) ;STORE THAT, TOO
CALL DNG1BY ;GET THE "FORWARD" BYTE
RET ;RAN OUT, GIVE BAD RETURN
TXNE T1,^-FWVST ;MAKE SURE IT'S NOT TOO BIG
RET ;IT'S TOO BIG
STOR T1,RMVST,(MB) ;STORE IT IN THE MESSAGE BLOC
RETSKP ;LOOKS GOOD, RETURN
;Here we have a Phase II message. Set the Phase II flag in the message
;block and return.
RTRHD1: SETONE RMPH2,(MB) ;SAY THIS IS A PHASE II MESSAGE
RETSKP ; AND GIVE GOOD RETURN
;Here with a control message. Check the type and return.
RTRHDC: TXNE T1,^-<CMTYP!CMCTL> ;MAKE SURE THE RESERVED BITS ARE ZERO
RET ;NOPE, GIVE BAD RETURN
LOAD T2,CMTYP,+T1 ;GET THE CONTROL MESSAGE TYPE
STOR T2,RMCTY,(MB) ;STORE THAT IN MESSAGE BLOCK
CALL DNG2BY ;GET THE ADDRESS
RET ;RAN OUT OF MESSAGE, GIVE ERROR RETURN
STOR T1,MBSRC,(MB) ;AND STORE IT IN PUBLIC SECTION
RETSKP ;RETURN TO SENDER WITH GOOD RETURN
SUBTTL RTRPH2 - Handle Phase II Messages
;RTRPH2 - Process Phase II messages
;
; Call:
; RC/ Pointer to circuit block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1,T3
;
;RTRPH2 handles all of the Phase II messages that we get. We check to see
;if the message is either a Node Initialization or a Node Verification message,
;if it is then we handle them in a similar manner to the Router
;Initialization and the Router Verification messages respectively. All
;types of messages are known to NSP and are passed to the "PHASE2" NSP. Note
;that that it can only be passed to the NSP which we believe is prepared to
;handle Phase II messages and that there can be only one of these nodes. (This
;is a hole in the multi-NSP sceme).
RTRPH2:
IFE FTPHA2, BUG PH2,CHK,<Shouldn't have gotten Phase II Message>,RTN
SAVEAC <P1,P2,FREE0> ;SAVE A PEA
LOAD T1,RMFST,(MB) ;GET THE FIRST BYTE OF THE MESSAGE
TXNN T1,RM%MB1 ;IF MUST BE ONE BIT IS OFF, WE ARE AT MSGFLG
JRST RTRP2N ; SO THERE IS NO ROUTING HEADER
;Here we eat the RTHDR of the message.
CALL DNG1BY ;GET THE DSTNODE IMAGE COUNT
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CALL DNSKBY ;SKIP THAT MANY BYTES
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR
CALL DNG1BY ;GET THE SRCNODE IMAGE COUNT
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CALL DNSKBY ;SKIP THESE BYTES
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CALL DNGEBY ;GET THE MSGFLG FIELD
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
;Now we have the MSGFLG in T1. Check to see if it is either a Node Init (NI)
;message or a Node Verification (NV) message and if it is not, just forward
;the message to NSP.
RTRP2N: LOAD T2,MFSUB,+T1 ;GET THE SUBTYPE OF MESSAGE
LOAD T3,MFTYP,+T1 ;GET THE TYPE OF MESSAGE
CAIN T3,MFT.CT ;IS IT A CONTROL MESSAGE?
CAIE T2,MFC.ST ; OR THE START TYPE CONTROL MESSAGE?
JRST RTRP2F ;NO, BACK UP ONE BYTE AND FORWARD TO NSP
;Here to check out the STARTTYPE field.
CALL DNG1BY ;GET THE STARTTYPE FIELD
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CAIN T1,STT.NV ;IS IT A NODE VERIFICATION MESSAGE?
JRST RTRP2V ;YES, GO HANDLE IT
CAIE T1,STT.NI ;IS IT A NODE INITIALIZATION MESSAGE?
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR
;Here with a Phase II Node Initialization message. We simply go through
;the message and store the relavent parameters in the circuit block.
TRACE RTR,<Phase II Node Init message being processed>
LOAD T1,RCSTA,(RC) ;GET OUR CIRCUIT'S STATE
CAIE T1,RCS.TI ;IS IT IN TI WAIT?
BUG.(CHK,ROUWSP,ROUTER,SOFT,<Phase II Node Init received in wrong state>,,<
Cause: This BUG is not documented yet.
>,FREMSG)
;Get the address of the neighbor.
CALL DNGEBY ;GET THE SOURCE NODE NUMBER
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
SKIPLE T1 ;RANGE CHECK IT
CAMLE T1,RTRMXN ; DOES IT LOOK OK?
BUG.(INF,ROUBNA,ROUTER,SOFT,<Bad node address in Phase II NI message>,,<
Cause: This BUG is not documented yet.
>,FREMSG)
STOR T1,RCNAD,(RC) ;STORE IT IN THE CIRCUIT BLOCK
;Skip the ASCII node name.
CALL DNG1BY ;GET THE IMAGE COUNT OF NODE NAME
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CAILE T1,6 ;IS LENGTH OK?
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
CALL DNSKBY ;SKIP THOSE BYTES
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
;Skip the FUNCTION field.
CALL DNGEBY ;READ THE FUNCTION FIELD
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
;Check out the REQUEST field.
CALL DNGEBY ;GET THE REQUEST FIELD
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
MOVX T2,RCVRQ ;VERFICATION REQUEST BIT IN MESSAGE BLOCK
ANDCAM T2,RC.VRQ(RC) ;ASSUME IT'S NOT REQUIRED
TXNE T1,REVER ;IS IT REQUIRED?
IORM T2,RC.VRQ(RC) ;YES, SET IT
;Get and store useless BLOCKSIZE.
CALL DNG2BY ;GET THE BLOCKSIZE
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCBSZ,(RC) ;STORE IT FOR NOTHING
;Skip MAXLINKS field
CALL DNG2BY ;IGNORE MAXLINK
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
;Get and store the version, eco level and customer args
CALL DNG1BY ;GET THE VERSION
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCVER,(RC) ;STORE IT
CALL DNG1BY ;GET THE ECO LEVEL
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCECO,(RC) ;STORE IT
CALL DNG1BY ;GET THE CUSTOMER ARGUMENT
CALLRET RTEMFE ;++MESSAGE FORMAT ERROR EVENT
STOR T1,RCCUS,(RC) ;STORE THIS ALSO
;The rest of the NI message is useless for us. Just set the node type
;to a Phase II node and build the verification message if needed.
MOVX T1,RCT.P2 ;NODE TYPE = PHASE II
STOR T1,RCNTY,(RC) ;STORE IN CIRCUIT BLOCK
MOVX T1,NTV.P2 ;ALSO PUT IT IN NODE TYPE VECTOR
CALL RTNSNT ; AS A PHASE II NODE
TMNN RCVRQ,(RC) ;IS VERIFICATION REQUIRED?
JRST RTRP2M ;NOT NEEDED
MOVX T2,4 ;WE NEED FOUR BYTES FOR MSGLFG AND COUNT
MOVE T1,MB ;RE-USE THE MESSAGE WE JUST GOT IN
CALL DNMINI ;RE-INITIALIZE IT
RET ;COULDN'T GET MESSAGE BLOCK, RETURN
XMOVEI T1,UD.MSD(MB) ;POINT TO THE MESSAGE SEGMENT WE GOT
CALL DNPINI ;SET UP THE BYTE POINTERS
SETZ T1, ;START MAKING UP THE BYTE
MOVX T2,MFT.CT ;TYPE IS CONTROL MESSAGE
STOR T2,MFTYP,+T1 ;STORE THE TYPE FIELD
MOVX T2,MFC.ST ;SUB-TYPE IS START MESSAGE
STOR T2,MFSUB,+T1 ;STORE THE SUB-TYPE FIELD
CALL DNPEBY ;WRITE THE EXTENSIBLE BYTE
MOVX T1,STT.NV ;STARTTYPE IS NODE VERIFICATION
CALL DNP1BY ;WRITE THE BYTE
MOVX T2,^D8 ;PASSWORD FIELD FOR PHASE II IS ALWAYS 8 BYTES
SOJGE T2,[SETZ T1, ;WRITE THE NULL BYTES
CALL DNP1BY ;PUT IN MESSAGE SEGMENT
JRST .] ;KEEP IT GOING TILL DONE
;All done, set the state to Verification Wait and queue the message to the
;DLL.
MOVX T1,RCS.TV ;NEW STATE WILL BE "TV" WAIT
STOR T1,RCSTA,(RC) ;STORE IT IN CIRCUIT BLOCK
TRACE RTR,<Sending Phase II Node Verification message>
INCR RCCMQ,(RC) ;INCREMENT NUMBER OF MESSAGES QUEUED
CALL CALQOB ;OUTPUT THE MESSAGE
SETZ MB, ;SAY THAT WE USED THE OLD MESSAGE ALREADY
;Merge here when we don't have to send a Node Verification Message.
;Now that we know the neighbor is a Phase II node, we must send him
;a NI message in return.
RTRP2M: SKIPE T1,MB ;IF WE HAVE AN OLD MESSAGE BLOCK
JRST [MOVX T2,NI.MXL ; LET'S USE IT
CALL DNMINI ; BY RE-INITIALIZING IT
RET ;OOPS, CAN'T DO IT
JRST RTRPM1] ;MERGE WITH OTHER CODE
MOVX T1,NI.MXL ;GET ROOM FOR MAX NI MESSAGE
CALL DNGMSG ;GET THAT BIG OF A MESSAGE BLOCK
RET ;COULDN'T GET IT, JUST RETURN
MOVE MB,T1 ;SET UP MB
RTRPM1: XMOVEI T1,UD.MSD(MB) ;WE WILL PUT BYTES IN THE USER DATA SEGMENT
CALL DNPINI ;SET UP TO DO THAT
SETZ T1, ;START MAKING UP THE BYTE
MOVX T2,MFT.CT ;TYPE IS CONTROL MESSAGE
STOR T2,MFTYP,+T1 ;STORE THE TYPE FIELD
MOVX T2,MFC.ST ;SUB-TYPE IS START MESSAGE
STOR T2,MFSUB,+T1 ;STORE THE SUB-TYPE FIELD
CALL DNPEBY ;WRITE THAT EXTENSIBLE BYTE
MOVX T1,STT.NI ;TYPE IS NODE INIT
CALL DNP1BY ;WRITE THE BYTE
MOVE T1,RTRADR ;GET OUR LOCAL ADDRESS
CALL DNPEBY ;PLACE IN NI MESSAGE
MOVE T1,RTRADR ;GET OUR LOCAL ADDRESS
CALL SCTA2N ;GET LOCAL NODE NAME FROM THAT
TDZA P1,P1 ;COULDN'T FIND IT, DON'T SEND A NAME
MOVE P1,T1 ;SAVE NAME
SETZ P2, ;ZERO BYTES AS OF YET.
MOVE T3,[POINT 6,P1] ;POINTER TO NODE NAME
MOVEI T4,6 ;MAXIMUM NUMBER OF BYTES TO LOOK AT
SOJG T4,[ILDB T2,T3 ;GET A BYTE
JUMPE T2,.+1 ;IF ZERO, DONE.
AOJA P2,.] ;LOOK AT NEXT BYTE.
MOVE T1,P2 ;NUMBER OF BYTES IN THE NODE NAME
CALL DNP1BY ;PLACE THE COUNT IN THE MESSAGE
MOVE FREE0,[POINT 6,P1] ;BYTE POINTER TO THE NODE NAME
SOJGE P2,[ILDB T1,FREE0 ;GET A BYTE FROM THE NAME
ADDI T1,^O40 ;MAKE IT ASCII (FROM SIXBIT)
CALL DNP1BY ;PLACE IT IN THE MESSAGE
JRST .] ; AND CONTINUE UNTIL DONE
SETZ T1, ;WE DON'T PERFORM ANY FUNCTIONS
CALL DNPEBY ;WRITE THE FUNCTIONS BYTE
;RTRPH2 - Continued from last page
SETZ T1, ;SET UP THE REQUESTS BYTE
SKIPE RTRVRQ ;IS VERIFICATION REQUIRED?
TXO T1,REVER ;YES, SET THE BIT IN REQUEST BYTE
CALL DNPEBY ;WRITE THE REQUESTS BYTE
MOVE T1,RTRBSZ ;GET OUR BLOCKSIZE
CALL DNP2BY ;WRITE THE BLKSIZE
MOVE T1,RTRBSZ ;GET OUR BLOCKSIZE
CALL DNP2BY ;USE IT AS NSPSIZ ALSO (IS THIS OK?)
SETZ T1, ;NEXT IS NSPVER, AND I DON'T CARE
CALL DNP2BY ;SO, I'LL SEND THREE ZEROES
SETZ T1, ;ANOTHER ONE
CALL DNP1BY ;WRITE IT
MOVX T1,^D4095 ;PUT IN A MAX MAXLINKS
CALL DNP2BY ;WRITE THE BYTES
MOVE T1,RTRVER ;GET OUR VERSION
CALL DNP1BY ;PUT IT IN AS COMVER (VERSION)
MOVE T1,RTRECO ;GET OUR ECO LEVEL
CALL DNP1BY ;PUT IT IN AS COMVER (ECO LEVEL)
MOVE T1,RTRCUS ;GET OUR CUSTOMER ARGUMENT
CALL DNP1BY ;PUT IT IN AS COMVER (CUSTOMER ARGUMENT)
IFN FTOPS20,<
SETZ T1, ;IF WE ARE TOPS20, WE WON'T SEND A NAME
CALL DNP1BY ; SO WRITE A ZERO COUNT
>
IFN FTOPS10,<
MOVX T1,^D25 ;WE'LL SEND ALL OF THE CONFIG TEXT
CALL DNP1BY ;WRITE THE IMAGE COUNT
MOVE P1,[POINT 7,CONFIG##] ;POINT TO CONFIGURATION TEXT
MOVX P2,^D25 ;SET UP A COUNT
SOJGE P2,[ILDB T1,P1 ;GET A BYTE FROM CONFIG
CALL DNP1BY ;PLACE IT IN THE MESSAGE
JRST .] ; AND CONTINUE UNTIL WE USED 32 BYTES
>
;Now send the message
TRACE RTR,<Sending Phase II Node Init message>
INCR RCCMQ,(RC) ;INCREMENT NUMBER OF MESSAGES QUEUED
CALL CALQOB ;SEND IT OUT.
;Now set the reachable bit in the routing vector for the Phase II
;neighbor.
D36OFF ;TURN OFF INTERRUPTS FOR A BIT
MOVE P1,RTRNRV ;POINT TO THE NORMAL ROUTING VECTOR
OPSTR <ADD P1,>,RCNAD,(RC) ;FIND THE PHASE II NEIGHBOR'S ENTRY
SETONE RNRCH,(P1) ;SAY THAT IT'S REACHABLE
ADD P1,RTROFS ;CALCULATE OUTPUT VECTOR POINTER
MOVEM RC,(P1) ; AND STORE THE PTR TO CIRCUIT TO REACH IT ON
SETZM RTRCKS ;RECALCULATE THE CHECKSUM LATER
D36ON ;END INTERLOCKED CODE
MOVX T1,RCS.RN ;NEW STATE WILL BE OK
STOR T1,RCSTA,(RC) ;STORE IT
CALLRET RTELUP ;TO SENDER
;Here to back up one byte (over MSGFLG) and forward the Phase II message
;to NSP.
RTRP2F: LOAD T1,RCNAD,(RC) ;GET THE NEIGHBORS ADDRESS
STOR T1,MBSRC,(MB) ;IT MUST HAVE COME FROM HIM
MOVE T1,RTRADR ;GET THE ADDRESS OF US
STOR T1,MBDST,(MB) ;STORE THAT IN MESSAGE FOR NSP
MOVX T1,^D1 ;MOVE BACK ONE BYTE
CALL DNBKBY ;GO BACK
MOVX T3,NV.RCV ;GIVE THE RECIEVED DATA ENTRY
MOVE T4,MB ;POINT TO MESSAGE WHICH CAME IN
CALLRET NSPRTR ;CALL NSP
;Here to handle the Phase II Node Verification Message.
RTRP2V: TRACE RTR,<Phase II Node Verification Message being processed>
LOAD T1,RCSTA,(RC) ;GET THE CIRCUIT STATE
CAIE T1,RCS.TV ;ARE WE WAITING FOR THIS NODE VERIFICATION?
BUG.(CHK,ROUWPV,ROUTER,SOFT,<Phase II Node Verif recieved in wrong state>,,<
Cause: This BUG is not documented yet.
>,FREMSG)
CALLRET RTRP2M ;SET OUR ENTRY IN ROUTING VECTOR AND
; SET STATE TO RUN
SUBTTL Network Management Interface -- RTNSNT - Set node type
;RTNSNT - Set a node's type in the node type vector
;
; Call:
; T1/ Node number
; T2/ Node type (NTV.xx)
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T3
;
;The node type vector is presently used only for one purpose; that is to
;define which nodes in the network are Phase II. Because messages may
;come from a phase II+ node, looking like Phase III messages, we must have
;some way of knowing that we cannot through them away on a resource
;failure.
RTNSNT::MOVE T3,[POINT NT.WID,RTRNTV] ;MAKE UP BYTE POINTER TO VECTOR
ADJBP T1,T3 ;FIND THE RIGHT ENTRY
DPB T2,T3 ;PLACE THE NEW ONE IN
RET ; AND RETURN TO USER
SUBTTL Network Management Interface -- RTNRNT - Read node's type
;RTNRNT - Read a node's type from the node type vector
;
; Call:
; T1/ Node number
; Return:
; RET ;ALWAYS, WITH T1 CONTAINING THE NODE TYPE
;
; Uses: T1-T3
RTNRNT::MOVE T3,[POINT NT.WID,RTRNTV] ;MAKE UP THE BYTE POINTER
ADJBP T1,T3 ;FIND THE ENTRY
LDB T1,T3 ;GET THE NODE'S TYPE
RET ; AND RETURN
SUBTTL Network Management Interface -- RTNSLS - Set Circuit State
;RTNSLS - Network Management call to set circuit state
;
; Call:
; T1/ Line id
; T2/ State to set the circuit to
;
; Return:
; RET ;COULDN'T PERFORM FUNCTION
; RETSKP ;NORMAL RETURN
;
; Uses: T1-T4
;
;Note that a circuit does not exist until it has been set on for the first
;time with network management.
RTNSLS::SAVEAC <P1,RC> ;SAVE FOR CIRCUIT STATE, AND RTRGCB
MOVE P1,T2 ;SAVE THE STATE WE WANT
CALL RTRGCB ;LOAD UP RC WITH CIRCUIT BLOCK
RET ;COULDN'T FIND BLOCK
MOVE T2,P1 ;GET STATE WE WANT
CAXL T2,NCK.ON ;IS THE FUNCTION LESS THAN LOWEST?
CAXLE T2,NCK.SR ;OR GREATER THAN HIGHEST?
BUG.(CHK,ROUSOR,ROUTER,SOFT,<Setting state out of range>,,<
Cause: This BUG is not documented yet.
>,RTN)
JRST @[IFIW RTNSS1 ;DO SET STATE ON
IFIW RTNSS3 ;DO SET STATE OFF
IFIW RTNSS5](T2) ;DO SET STATE SERVICE
;Set the circuit state to ON.
RTNSS1: LOAD T1,RCSTA,(RC) ;GET THE CURRENT CIRCUIT STATE
CAIE T1,RCS.TT ;IS IT IN TEST MODE
CAIN T1,RCS.RN ; OR RUNNING OK?
RET ;SHOULDN'T BE DOING THIS THEN
MOVX T1,RCS.WT ;NOW IT'S IN WAIT STATE
STOR T1,RCSTA,(RC) ;STORE IT
CALL R2KINI ;RE-START THE DLL
RETSKP ; AND GIVE GOOD RETURN
;Set the circuit state to OFF.
RTNSS3: CALL R2KHLT ;TRY TO HALT THIS CIRCUIT
CALL RTRZCB ;ZAP THE CIRCUIT BLOCK
SETOM RTRRCF ;FLAG FOR RECOMPUTING
RETSKP ;AND RETURN
;Set the circuit state to SERVICE.
RTNSS5: LOAD T1,RCSTA,(RC) ;GET CURRENT STATE
CAXN T1,RCS.RN ;IS IT RUNNING?
RET ;YES, TELL HIM WHERE TO GO.
MOVX T1,RCS.TT ;TEST STATE (SERVICE)
STOR T1,RCSTA,(RC) ;STORE.
RETSKP ;AND TELL HIM IT WORKED
SUBTTL Network Management Interface -- RTNGLS - Circuit state routine
;RTNGLS - Circuit state routine for NMX
;
;Call
; T1/ Line-id
;Return
; RET ;Invalid line-id
; RETSKP ;T1 contains circuit state in NCK.xx number
RTNGLS::SAVEAC RC ;SAVE CIRCUIT BLOCK POINTER
CALL RTRGCB ;LOAD UP C WITH CIRCUIT BLOCK
RET ;NO SUCH CIRCUIT
LOAD T1,RCSTA,(RC) ;GET RTR'S VERSION OF CIRCUIT STATE
CAXL T1,RCS.OF ;IS LESSER THAN MINUMUM
CAXLE T1,RCS.RN ;OR GREATER THAN MAX
BUG.(CHK,ROUIVL,ROUTER,SOFT,<Invalid circuit state>,,<
Cause: This BUG is not documented yet.
>,RTN)
MOVE T1,<-RCS.OF>+[NCK.OF ;RCS.OF
NCK.ON ;RCS.WT
NCK.ON ;RCS.TI
NCK.ON ;RCS.TV
NCK.SR ;RCS.TT
NCK.ON](T1) ;RCS.RN
RETSKP
SUBTTL Network Management Interface -- RTNGLB - Circuit substate
;RTNGLB - Circuit substate for NMX
;
;Call
; T1/ Line-id
;Return
; RET ;no substate for this state
; RETSKP ;T1 contains substate in NCB.xx number
RTNGLB::SAVEAC RC ;SAVE CIRCUIT BLOCK POINTER
CALL RTRGCB ;LOAD UP RC WITH CIRCUIT BLOCK
RET ;NO SUCH CIRCUIT (SHOULDN'T HAPPEN)
SETO T1, ;START WITH ILLEGAL SUBSTATE
LOAD T2,RCSTA,(RC) ;GET RTR'S VERSION OF CIRCUIT STATE
CAXN T2,RCS.WT ;IS IT WAITING (SYNCHRONIZING)?
MOVX T1,NCB.SN ; SUBSTATE SYNCH
CAXE T2,RCS.TI ;SENDING TI'S?
CAXN T2,RCS.TV ;OR WAITING FOR A VERIFICATION?
MOVX T1,NCB.ST ; SUBSTATE STARTING
JUMPL T1,RTN ;IF NO SUBSTATE GIVE NON-SUCCESS RETURN
RETSKP ;SAY WE HAVE A SUBSTATE.
SUBTTL Network Management Interface -- RTNLID - Give the line id
;RTNLID - Give the line id for a given node
;
;Call
; T1/ Node address
;Return
; RET ;node unreachable
; RETSKP ;T1 contains line-id
RTNLID::CAMG T1,RTRMXN ;OUT OF RANGE?
JUMPG T1,RTNLI1 ;BELOW RANGE, MAYBE?
BUG.(CHK,ROUNMR,ROUTER,SOFT,<NMX out of range>,,<
Cause: This BUG is not documented yet.
>,RTN)
RTNLI1: ADD T1,RTRNRV ;ADD IN THE VECTOR ADDRESS
TMNN RNRCH,(T1) ;IS NODE REACHABLE?
RET ;NOPE, TELL CALLER.
ADD T1,RTROFS ;NOW POINT TO OUTPUT CIRCUIT VECTOR
MOVE T1,(T1) ;GET THE OUTPUT CIRCUIT POINTER
LOAD T1,RCLID,(T1) ;GET LINE ID FROM CIRCUIT BLOCK
RETSKP ;SUCCESS.
SUBTTL Network Management Interface -- RTRNMX - Do circuit functions
;RTRNMX - Do circuit functions for NMX
;
;Call
; T1/ Line id
; T2/ 18 bit local pointer to byte pointer withing RC begstr
; T3/ Pointer to NX block
;Return
; RET ;
; RETSKP ;Value in NXVAL,(NX)
RTRNMX::SAVEAC <P1,P2,RC> ;WORK AREA
SKIPE P1,T2 ;IF SECONDS SINCE LAST ZEROED, LEAVE ZERO
MOVE P1,(T2) ;GET BYTE POINTER
MOVE P2,T3 ;SAVE POINTER TO NX BLOCK
CALL RTRGCB ;GET CIRCUIT BLOCK POINTER
RET ;NO SUCH CIRCUIT
JUMPE P1,RTNNM3 ;SECONDS SINCE LAST ZEROED IS SPECIAL CASED.
LOAD T2,NXVAL,(P2) ;GET VALUE IN CASE NEEDED
TMNN NXWRM,(P2) ;ARE WE WRITING ON THE MONITOR?
JRST RTNNM2 ;NOPE, WE ARE ONLY READING
LDB T1,P1 ;GET CURRENT VALUE
DPB T2,P1 ;STORE OUR VALUE ON TOP OF ANYTHING THERE
RETSKP ;WE FINISHED
RTNNM2: LDB T1,P1 ;GET VALUE FROM CIRCUIT BLOCK
RETSKP ;RETURN WITH ANSWER IN CORRECT SPOT
RTNNM3: CALL DNGTIM ;GET CURRENT TIME STAMP.
TMNE NXZMC,(P2) ;ARE WE ZEROING SECONDS SINCE LAST ZEROED?
JRST RTNNM4 ;YES, GET CURRENT TIME.
OPSTR <SUB T1,>,RCSLZ,(RC);SUBTRACT LAST TIME STAMP
IDIVI T1,TIMBAS ;CONVERT TO SECONDS.
RETSKP ;RETURN SUCCESS.
RTNNM4: LOAD T2,RCSLZ,(RC) ;GET PREVIOUS TIME
STOR T1,RCSLZ,(RC) ;STORE CURRENT TIME STAMP.
SUB T1,T2 ;SUBRACT TIME STAMPS
IDIVI T1,TIMBAS ;AND CONVERT TO SECONDS
RETSKP ;RETURN SUCCESS, WE DID IT.
RTLBSZ::POINTR(RC.BSZ(RC),RCBSZ)
RTLCST::POINTR(RC.CST(RC),RCCST)
RTLTM3::POINTR(RC.TM3(RC),RCTM3)
RTLTM4::POINTR(RC.TM4(RC),RCTM4)
RTLNAD::POINTR(RC.NAD(RC),RCNAD)
RTLCAP::POINTR(RC.CAP(RC),RCCAP)
RTLCDP::POINTR(RC.CDP(RC),RCCDP)
RTLCAL::POINTR(RC.CAL(RC),RCCAL)
RTLCTR::POINTR(RC.CTR(RC),RCCTR)
RTLCTS::POINTR(RC.CTS(RC),RCCTS)
RTLCTL::POINTR(RC.CTL(RC),RCCTL)
RTLCCD::POINTR(RC.CCD(RC),RCCCD)
RTLCIF::POINTR(RC.CIF(RC),RCCIF)
RTLBYR::POINTR(RC.BYR(RC),RCBYR)
RTLBYS::POINTR(RC.BYS(RC),RCBYS)
RTLDBR::POINTR(RC.DBR(RC),RCDBR)
RTLDBS::POINTR(RC.DBS(RC),RCDBS)
RTNRCH::POINTR(RN.RCH(T2),RNRCH)
RTNLCL::POINTR(RN.LCL(T2),RNLCL)
RTNCST::POINTR(RN.CST(T2),RNCST)
RTNHOP::POINTR(RN.HOP(T2),RNHOP)
SUBTTL Network Management Interface -- Router Event Types
;These are the various events that occur in router which are reported
;to network management.
DEFINE EVENTS,<
RE APL,0, NON,RTEPKH ;AGED PACKET LOSS
RE NUR,1, CKT,RTEPKH ;NODE UNREACHABLE PACKET LOSS
RE NOR,2, CKT,RTEPKH ;NODE OUT-OF-RANGE PACKET LOSS
RE OPL,3, CKT,RTEPKH ;OVERSIZED PACKET LOSS
RE PFE,4, CKT,RTEPKB ;PACKET FORMAT ERROR
RE PRL,5, CKT,<RTEPKH,RTEHIA> ;PARTIAL ROUTING UPDATE LOSS
RE VRJ,6, CKT,RTENOD ;VERIFICATION REJECT
RE LDL,7, CKT,RTEREA ;CIRCUIT DOWN, CIRCUIT FAULT
RE LDS,8, CKT,<RTEREA,RTEPKH> ;CIRCUIT DOWN, SOFTWARE FAULT
RE LDO,9, CKT,<RTEREA,RTEPKH,RTEEXN> ;CIRCUIT DOWN, OPERATOR FAULT
RE LUP,10,CKT,RTENOD ;CIRCUIT UP
RE IFL,11,CKT,RTEREA ;INITIALIZATION FAILURE, CIRCUIT FAULT
RE IFS,12,CKT,<RTEREA,RTEPKH> ;INITIALIZATION FAILURE, SOFTWARE FAULT
RE IFO,13,CKT,<RTEREA,RTEPKH> ;INITIALIZATION FAILURE, OPERATOR FAULT
RE NRC,14,NOD,RTESTA ;NODE REACHABILITY CHANGE
>
DEFINE RE(EVENT,TYPE,ENTTYP,PARAMS),<
RE.'EVENT==^D<TYPE>> ;DEFINE THE RE MACRO
;Now expand the symbols.
EVENTS
;Now define the processor macro.
DEFINE RE(PREFIX,VALUE,ENTTYP,PARAMS),<
IFIW [MOVX T1,.NT'ENTTYP
STOR T1,NEETP,(P1)
SETZ T4, ;;INITIALIZE THE COUNT
IRP <PARAMS>,<
CALL PARAMS ;;STICK ON THE PARAMETER DATA
>
STOR T4,NEDLN,(P1) ;;GIVE ARG BLOCK THE LENGTH
RET]
>
;Make a table of event processors.
RTETAB: EVENTS
RET.LN==.-RTETAB
RET.MX==<.-RTETAB>-1
SUBTTL Network Management Interface -- Reason Definitions
;These are the various reasons which may be put in the reason field of
;events that include REASON as a event parameter.
DEFINE REASON(SUFFIX,VALUE),<
XP RS.'SUFFIX,^D'VALUE>
REASON LSL,0 ;CIRCUIT SYNCHRONIZATION LOST
REASON DTE,1 ;DATA ERRORS
REASON UPT,2 ;UNEXPECTED PACKET TYPE
REASON RUC,3 ;ROUTING UPDATE CHECKSUM ERROR
REASON ANA,4 ;ADJACENT NODE ADDRESS CHANGE
REASON VRT,5 ;VERIFICATION RECIEVE TIMEOUT
REASON VSK,6 ;VERSION SKEW
REASON ANO,7 ;ADJAGE
REASON ABS,8 ;ADJACENT NODE BLOCK SIZE TOO SMALL
REASON IVS,9 ;INVALID VERIFICATION SEED VALUE
REASON ALT,10 ;ADJACENT NODE LISTENER RECEIVE TIMEOUT
REASON ALI,11 ;ADJACENT NODE LISTENER RECEIVED INVALID DATA
PURGE REASON
SUBTTL Network Management Interface -- RTNEVT - Event Reporter
;RTNEVT - Report Router event
;
; Call:
; T1/ Event type
; T2/ Entity ID (we know the entity type from RTETAB)
; T3/ Event specific word (REASON, STATUS, etc.)
; T4/ Message Block Pointer or zero if none given
; (Message Block must be DNGINIized before this is called)
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T4
;
;This calls something which will call network management to log this event
;which has taken place. This routine is called by the EVENT macro.
XP EVTMLN,^D15 ;MAXIMUM LENGTH OF EVENT PARAMETER DATA (BYTES)
RTNEVT: SAVEAC <P1,P2,MB,MS> ;SAVE SOME ACS
SKIPL P2,T1 ;RANGE CHECK THE
CAILE P2,RET.MX ;EVENT TYPE
BUG.(CHK,ROUUET,ROUTER,SOFT,<Unknown event type in RTNEVT>,,<
Cause: This BUG is not documented yet.
>,RTN)
MOVE P1,T2 ;SAVE THE ENTITY-ID
MOVEM T3,RTREVW ;SAVE THE EVENT ARGUMENT [**FIX THIS**]
SKIPN MB,T4 ;SET UP MESSAGE BLOCK (IF ANY)
JRST RTNEV1 ;NOT THERE, DON'T TRY TO SET POSITION
JE RMMK1,(MB),RTNEV1 ;IF NO ROUTER HEADER, THEN SKIP THIS
MOVE T1,MB ;PASS POINTER TO MESSAGE BLK TO DNGINI
XMOVEI MS,RM.MSD(MB) ;POINT AT THE ROUTER MSD
TMNE RMICP,(MB) ;WAS THIS FROM THE LOCAL NSP?
XMOVEI MS,IN.MSD(MB) ;NO, POINT AT INPUT MSD
MOVX T1,<POINT 8,(T6)> ;VGNPTR. START AT BEGINNING OF MSD
STOR T1,MDPTR,(MS) ;STORE AS CURRENT POSITION IN MSD.
LOAD T1,RMMK1,(MB) ;GET ROUTER MARK
STOR T1,MDBYT,(MS) ;SAVE AS NUMBER OF BYTES LEFT TO DO.
RTNEV1: MOVX T1,NE.LEN+<<EVTMLN+3>/4> ;GET ENOUGH FOR ARG BLOCK AND
; MAXIMUM AMOUNT OF EVENT PARAMETER DATA
CALL DNGWDZ ;GET THE WORDS
BUG.(CHK,ROUCGV,ROUTER,SOFT,<Couldn't get memory for event arg block>,,<
Cause: This BUG is not documented yet.
>,RTN)
STOR P1,NEEID,(T1) ;PUT ENTITY-ID IN EVENT BLOCK
MOVE P1,T1 ;SAVE THE POINTER TO THE BLOCK
STOR P2,NECTY,(P1) ;PUT THE EVENT TYPE IN THE ARG BLOCK
MOVX T1,.NCRTR ;THE EVENT CLASS IS ROUTER
STOR T1,NECCL,(P1) ;PUT IN NE ARG BLOCK
XMOVEI T1,NE.LEN(P1) ;MAKE A FULLWORD POINTER TO DATA
STOR T1,NEDAT,(P1) ;STORE POINTER TO IT IN ARG BLOCK
MOVE T1,[POINT 8,NE.LEN(P1)] ;MAKE UP BYTE POINTER TO PARAMETER DATA
EXCH T1,P2 ;SWITCH FUNCTION AND POINTER
CALL @RTETAB(T1) ;CALL THE PARAMETER PROCESSOR
JN NEEID,(P1),RTNEV2 ;IF THERE IS AN ENTITY ID, GIVE IT TO NTMAN
SETONE NEETP,(P1) ;BE NICE TO SPEAR. IF NO ENTITY, SAY NONE.
RTNEV2: MOVE T1,P1 ;POINT TO THE ARG BLOCK
CALL NMXEVT ;GIVE THE EVENT
JFCL ;SO WHAT IF THE EVENT GETS LOST
MOVE T1,P1 ;GET POINTER TO BLOCK
CALLRET DNFWDS ;RETURN THE BLOCK OF CORE
SUBTTL Network Management Interface -- Event Parameter Processors
;Put a packet header in the NE argument block string. This corresponds to
;parameter 0 for circuit events.
RTEPKH: SKIPN MB ;MUST HAVE A MESSAGE BLOCK HERE
BUG.(CHK,ROUEHM,ROUTER,SOFT,<No Message Block for Event data>,,<
Cause: This BUG is not documented yet.
>,RTN)
JE RMMK1,(MB),RTEPKB ;NO ROUTER HEADER, THEN DON'T PUT A BLOCK 0 ON
MOVEI T1,0 ;GET PARAMETER NUMBER
MOVEI T2,2 ;GET NUMBER OF BYTES
CALL PUTNBT ;INSTALL THE BYTES SWAPPED
CALL DNG1BY ;GET THE "FIRST" BYTE FROM RTR MESSAGE
RET ;COULND'T GET IT, JUST RETURN
PUSH P,T1 ;SAVE MESSAGE FLAGS FOR LATER
TXNE T1,RM%CTL ;WAS IT A CONTROL MESSAGE?
SKIPA T1,[302] ;YES, CODED MULTIPLE, TWO FIELDS
MOVEI T1,304 ; NO, CODED MULTIPLE, FOUR FIELDS
CALL PUTBYT ;INSTALL DATA TYPE
MOVEI T1,041 ;NOT CODED, HEX NUMBER OF 1 BYTE
CALL PUTBYT ;INSTALL IT
MOVE T1,0(P) ;GET BACK THE REAL DATA
CALL PUTBYT ;OUTPUT IT
TXNE T1,RM%CTL ;IS IT A CONTROL MESSAGE???
JRST RTEPK1 ;YES, SKIP THIS
MOVEI T1,002 ;DECIMAL UNSIGNED, TWO BYTES
CALL PUTBYT ;OUTPUT THE DATA TYPE
MOVEI T2,2 ;NUMBER OF BYTES TO TRANSFER
CALL PUTNBY ;PUT DESTINATION NODE ADDRESS INTO DATA STRING
RTEPK1: MOVEI T1,002 ;DECIMAL UNSIGNED, TWO BYTES
CALL PUTBYT ;STUFF IT
MOVEI T2,2 ;NUMBER OF BYTES TO TRANSFER
CALL PUTNBY ;INSTALL FOURCE NODE ADDRESS
POP P,T1 ;GET BACK MESSAGE HEADER
TXNE T1,RM%CTL ;IS IT A CONTROL MESSAGE
JRST RTN ;YES, SKIP THIS ONE TOO
MOVEI T1,041 ;NOT CODED, HEX NUMBER OF 1 BYTE
CALL PUTBYT ;STUFF IT
MOVEI T2,1 ;TRANSFER ONE BYTE
CALL PUTNBY ;DO THE TRANSFER
RET ;WE RETURN ANYWAY
;Put a packet beginning in the NE argument block string.
RTEPKB: SKIPN MB ;MUST HAVE A MESSAGE BLOCK HERE
BUG.(CHK,ROUEHB,ROUTER,SOFT,<No Message Block for Event data>,,<
Cause: This BUG is not documented yet.
>,RTN)
MOVEI T1,1 ;GET PARAMETER NUMBER
MOVEI T2,2 ;GET NUMBER OF BYTES
CALL PUTNBT ;INSTALL THE BYTES SWAPPED
MOVEI T1,040 ;NOT CODED, HEX IMAGE
CALL PUTBYT ;INSTALL DATA TYPE
MOVEI T1,6 ;LENGTH OF DATA IS ALWAYS 6 BYTES
CALL PUTBYT ;INSTALL LENGTH OF DATA
MOVX T2,6 ;WE ALWAYS WANT SIX BYTES
CALL PUTNBY ; PUT THEM IN THE NE BLOCK
JFCL ;DON'T REALLY CARE
RET ; AND RETURN
;Put the Highest Address in the NE argument block string.
RTEHIA: MOVEI T1,2 ;GET PARAMETER NUMBER
MOVEI T2,2 ;GET NUMBER OF BYTES
CALL PUTNBT ;INSTALL THE BYTES SWAPPED
MOVEI T1,002 ;DECIMAL UNSIGNED, TWO BYTES
CALL PUTBYT ;OUTPUT IT
MOVEI T2,2 ;MOVE TWO BYTES
CALLRET PUTNBY ;COPY HIGHEST ADDRESS
;Put a node address in the NE argument block string.
RTENOD: MOVEI T1,3 ;GET PARAMETER NUMBER
RTEEX1: MOVEI T2,2 ;GET NUMBER OF BYTES
CALL PUTNBT ;INSTALL THE BYTES SWAPPED
MOVEI T1,301 ;CODED MULTIPLE, ONE FIELD
CALL PUTBYT ;INSTALL DATA TYPE
MOVEI T1,002 ;DECIMAL UNSIGNED, TWO BYTES
CALL PUTBYT ;INSTALL SUB-DATA TYPE
MOVE T1,RTREVW ;GET THE NODE NUMBER [**FIX THIS**]
MOVEI T2,2 ;NODE NUMBER IS TWO BYTES
CALLRET PUTNBT ;PUT THE NUMBER IN THE MESSAGE
;Put the Expected Node in the NE argument block string.
RTEEXN: LOAD T1,RCNAD,(RC) ;GET THE ADJACENT NODE
MOVEM T1,RTREVW ;SAVE FOR RTEEX1 [**FIX THIS**]
MOVEI T1,4 ;GET PARAMETER NUMBER
JRST RTEEX1 ;OTHEWISE, SAME AS NODE
;Put the REASON type in the NE argument block string.
RTEREA: MOVEI T1,5 ;GET PARAMETER NUMBER
RTEST1: MOVEI T2,2 ;GET NUMBER OF BYTES
CALL PUTNBT ;INSTALL THE BYTES SWAPPED
MOVEI T1,201 ;CODED, SINGLE FIELD, LENGTH 1 BYTE
CALL PUTBYT ;STUFF IT
MOVE T1,RTREVW ;GET THE REASON [**FIX THIS**]
CALLRET PUTBYT ;STUFF IT AND RETURN
;Put the status in the NE argument block. This is a one byte field
;which we have in RTREVW, so just use RTEREA.
RTESTA: MOVEI T1,7 ;GET PARAMETER NUMBER
JRST RTEST1 ;STATUS PARAM IS JUST LIKE REASON
SUBTTL Network Management Interface -- Event Processor Subroutines
;Put n (in T2) bytes in the string pointed to by the NE argument block.
;It also updates T4, which is the count of bytes put in so far.
PUTNBY: JUMPE T2,RTN ;RETURN IF NO MORE BYTES LEFT
CALL DNG1BY ;GET ONE BYTE FROM THE MESSAGE BLOCK
RET ;PROPAGATE FAILURE
IDPB T1,P2 ;STORE THE BYTE IN SOME SPACE
ADDI T4,1 ;UPDATE THE GLOBAL COUNT
SOJA T2,PUTNBY ;SEE IF WE HAVE TO PUT IN MORE
;Put n (in T2) bytes of the number in T1.
PUTNBT: JUMPE T2,RTN ;RETURN IF NOTHING LEFT
IDPB T1,P2 ;PUT THE BYTE IN THE MESSAGE
LSH T1,-^D8 ;SHIFT OVER TO THE NEXT BYTE
ADDI T4,1 ;UPDATE THE COUNT
SOJA T2,PUTNBT ;DO THE REST
;Put one byte (in T1) into the data string for network management
PUTBYT: IDPB T1,P2 ;INSTALL THE BYTE
AOJA T4,RTN ;INCREMENT THE NUMBER OF BYTES
SUBTTL Network Management Interface -- Miscellaneous Event Processors
;These are a bunch of routines to report different events. The events
;here are common to more than one routine, so they are collected
;together in this section.
;RTEMFE - Report Message Format Error Event
RTEMFE: LOAD T2,RCLID,(RC) ;GET THE LINE ID FOR ENTITY ID
EVENT RE.PFE,<Packet format error event>,MB
CALLRET FREMSG ;FREE MSG BLK AND RETURN
;RTEVRJ - Report Verficiation Reject Event
RTEVRJ: LOAD T2,RCLID,(RC) ;GET THE ENTITY ID (CIRCUIT)
LOAD T3,RCNAD,(RC) ; AND THE NEIGHBOR'S ADDRESS
EVENT RE.VRJ,<Verification reject event>
CALLRET FREMSG ;FREE MSG BLK AND RETURN
;RTELDL - Report Circuit Down, Hard Circuit Fault Event
RTELDL: MOVE T3,T1 ;GET THE REASON
LOAD T2,RCLID,(RC) ;GET THE LINE ID
EVENT RE.LDL,<Circuit down, circuit fault>
INCR RCCCD,(RC) ;INCREMENT THE CIRCUIT DOWN COUNTER
RET ;RETURN, NO MSG TO FREE HERE
;RTELDS - Report Circuit Down, Software Fault Event
RTELDS: MOVE T3,T1 ;GET THE REASON
LOAD T2,RCLID,(RC) ;GET THE LINE ID
EVENT RE.LDS,<Circuit down, software fault>,MB
INCR RCCCD,(RC) ;INCREMENT THE CIRCUIT DOWN COUNTER
CALLRET FREMSG ;FREE MSG BLK AND RETURN
;RTELDO - Report Circuit Down, Operator Fault Event
RTELDO: MOVE T3,T1 ;GET THE REASON
LOAD T2,RCLID,(RC) ;GET THE LINE ID
EVENT RE.LDO,<Circuit down, operator fault>,MB
INCR RCCCD,(RC) ;INCREMENT THE CIRCUIT DOWN COUNTER
CALLRET FREMSG ;FREE MSG BLK AND RETURN
;Event Processors - Continued from last page
;RTELUP - Report circuit up
RTELUP: LOAD T2,RCLID,(RC) ;GET THE ENTITY ID (CIRCUIT)
LOAD T3,RCNAD,(RC) ; AND THE NEIGHBOR'S ADDRESS
EVENT RE.LUP,<Circuit Up>
RET ;AND RETURN
;RTEINL - Report Initialization Failure, Hard Circuit Fault Event
RTEINL: MOVE T3,T1 ;GET THE REASON
LOAD T2,RCLID,(RC) ;GET THE LINE ID
EVENT RE.IFL,<Initialization failure, circuit fault>
INCR RCCCD,(RC) ;INCREMENT THE CIRCUIT DOWN COUNTER
RET ;RETURN, NO MSG BLK TO FREE HERE
;RTEINS - Report Initialization Failure, Software Fault Event
RTEINS: MOVE T3,T1 ;GET THE REASON
LOAD T2,RCLID,(RC) ;GET THE LINE ID
EVENT RE.IFS,<Initialization failure, software fault>,MB
INCR RCCCD,(RC) ;INCREMENT THE CIRCUIT DOWN COUNTER
CALL FREMSG ;FREE MSG BLK AND RETURN
CALLRET R2KINI ;RE-INITIALIZE THE DLL
;RTEINO - Report Initialization Failure, Operator Fault Event
RTEINO: MOVE T3,T1 ;GET THE REASON
LOAD T2,RCLID,(RC) ;GET THE LINE ID
EVENT RE.IFO,<Initialization failure, operator fault>,MB
INCR RCCCD,(RC) ;INCREMENT THE CIRCUIT DOWN COUNTER
CALL FREMSG ;FREE MSG BLK AND RETURN
CALLRET R2KINI ;RE-INITIALIZE THE DLL
SUBTTL Miscellaneous Routines -- RTRZCB - Zap Circuit Block
;RTRZCB - Zap circuit block and report circuit down event
;
; Call:
; RC/ Pointer to circuit block
;
; Return:
; RET ;ALWAYS
;
;This routine clears out a circuit block (usually when it goes down),
;and returns any messages which may have been queued up on it.
RTRZCB: LOAD T1,RCLRM,(RC) ;POINTER TO LAST ROUTING MESSAGE
SKIPE T1 ;IF WE HAVE ONE
CALL DNFMSG ;FREE IT
RTRZC1: D36OFF ;RETURN ALL BUFFERS ON THE QUEUE.
DEQUE T3,RC.JSQ(RC),MB.NXT,RTRZC2
D36ON
CALL RTIOTC ;CALL OUTPUT INCOMPLETE.
JRST RTRZC1 ;AND LOOP
RTRZC2: D36ON ;CANCEL D36OFF FROM RTRZC1
SETZRO <RCNAD,RCLRM,RCTLR,RCFLG>,(RC) ;CLEAR A BUNCH OF FIELDS:
; NEIGHBOR,
; LAST ROUTING MESSAGE,
; TIME OF LAST ROUTING MESSAGE,
; AND FLAGS.
RET ;RETURN TO SENDER
SUBTTL Miscellaneous Routines -- RTRMCB - Make a Circuit Block
;RTRMCB - Make a new circuit block and store the defaults
;
; Call:
; T1/ Line id
;
; Return:
; RET ;COULDN'T ALLOCATE BLOCK
; RETSKP ;EVERYTHING WORKED, T1 CONTAINING CIRCUIT BLOCK
; ; POINTER
; Uses: T1-T4
RTRMCB: SAVEAC P1 ;SAVE A PEA
MOVE P1,T1 ;SAVE THE LINE ID
MOVX T1,RC.LEN ;GET THE LENGTH OF A CIRCUIT BLOCK
CALL DNGWDZ ;GET THAT MANY WORDS
RET ;RETURN A FAILURE
STOR P1,RCLID,(T1) ;STORE THE LINE ID
MOVX T2,%RTTM3 ;GET THE DEFAULT HELLO MESSAGE TIMER VALUE
STOR T2,RCTM3,(T1) ;STORE IT IN THE CIRCUIT BLOCK
MOVX T2,%RTTM4 ;GET THE DEFAULT LISTENER TIME-OUT VALUE
STOR T2,RCTM4,(T1) ;STORE IT IN THE CIRCUIT BLOCK
MOVX T2,%RTCST ;GET DEFAULT COST FOR A CIRCUIT
STOR T2,RCCST,(T1) ;STORE IT IN THE CIRCUIT BLOCK
MOVX T2,RCS.OF ;INITIAL STATE WILL BE "OFF"
STOR T2,RCSTA,(T1) ;STORE STATE CODE
MOVE P1,T1 ;SAVE THE CIRCUIT BLOCK POINTER
AOS RTRNLN ;INCREMENT THE NUMBER OF CIRCUITS
MOVX T1,2 ;GET NEW EMERGENCY BUFFERS FOR THIS CIRCUIT
CALL DNGEBF ;1 FOR KEPT ROUTING MSG, 1 FOR ROUTE-THROUGH
BUG.(CHK,ROUCGE,ROUTER,SOFT,<Couldn't get emergency buffer for circuit>,,<
Cause: ROUTER requires that the memory manager save at least 2 buffers
per link for ROUTER, one for the routing message ROUTER keeps for
each circuit and one to guarantee some level of route-through ability.
ROUTER was asked to open a circuit, but the memory manager could
not guarantee the buffers.
Cure: Allocate more memory or settle for fewer circuits.
>)
CALL DNGTIM ;GET CURRENT TIME OF DAY
STOR T1,RCSLZ,(P1) ;STORE FOR USE BY SECONDS SINCE LAST ZEROED
MOVE T1,P1 ;RETURN THE CIRCUIT BLOCK POINTER IN T1
RETSKP ;RETURN SUCCESS
SUBTTL Miscellaneous Routines -- RTRGCB - Get Circuit Block Pointer
;RTRGCB - Get circuit block pointer from line id
;
; Call:
; T1/ Line id
;
; Return:
; RET ;WHEN WE COULDN'T FIND A MATCH
; RETSKP ;WHEN SUCCESSFUL, WITH C POINTING TO THE
; ; CIRCUIT BLOCK
;
; Uses: T1,T2
;
;There aren't that many circuits, so a simple search is not too bad.
RTRGCB: SKIPN RC,RTRCBQ ;START LOOKING AT FIRST CIRCUIT
RET ;NONE THERE, JUST RETURN
RTRGC1: LOAD T2,RCLID,(RC) ;GET IT'S LINE ID
CAMN T1,T2 ;IS IT THE ONE WE'RE LOOKING FOR?
RETSKP ;GOOD RETURN (I SKIP OVER RETSKPS
; IF YOU DON'T LIKE THAT CHANGE IT)
LOAD RC,RCNXT,(RC) ;GET THE NEXT CIRCUIT BLOCK
JUMPN RC,RTRGC1 ;GO CHECK IT OUT
RET ;COULDN'T FIND IT, OH WELL
;Routine used by network management to load up RCKBA before calling KONDSP
RTRKBA::SAVEAC RC ;PRESERVE
CALL RTRGCB ;FIND THE CIRCUIT BLOCK
RET ;FAILED
LOAD T2,RCKBA,(RC) ;GET THE KONTROLLER BLOCK ADDRESS
RETSKP
SUBTTL Miscellaneous Routines -- CPYMSG - Copy all MSDs together
;CPYMSG - Gather all the MSDs into one (IN.MSD) in a new message block
;
; Call:
; MB/ Pointer to message block to make a copy of
;
; Return:
; RET ;ON FAILURE
; RETSKP ;DONE, WITH T1 POINTING TO THE NEW MESSAGE
;
; Uses: T1-T4
;
;Only the portions of the message block which are relavent to Router
;are copied, because the copied message will be sent to NSP, which
;believes that the message has come in over the network.
CPYMSG: CALL DNCPMS ;COPY MB'S MSDs INTO A NEW BLOCK
RET ;PROPOGATE ERROR
;T1 POINTS TO NEW MSG BLK
;Now copy all the relavent fields.
LOAD T2,RMFST,(MB) ;GET THE FIRST BYTE
STOR T2,RMFST,(T1) ; AND COPY IT
LOAD T2,RMOCP,(MB) ;GET THE OUTPUT CIRCUIT
STOR T2,RMOCP,(T1) ; AND COPY IT
LOAD T2,RMICP,(MB) ;GET THE INPUT CIRCUIT
STOR T2,RMICP,(T1) ; AND COPY IT (MONOTONOUS, ISN'T IT)
LOAD T2,MBSRC,(MB) ;GET SOURCE NODE ADDRESS
STOR T2,MBSRC,(T1) ; AND COPY IT INTO THE NEW COPY
LOAD T2,MBDST,(MB) ;GET THE DESTINATION NODE ADDRESS
STOR T2,MBDST,(T1) ; AND COPY IT INTO THE NEW COPY
RETSKP ;RETURN SUCCESS, T1 PTS TO NEW MSG BLK
SUBTTL Miscellaneous Routines -- FREMSG - Toss a Message
;FREMSG - Return an unwanted message to rightful sink
;
; Call:
; MB/ Pointing to Message Block
;
; Return:
; RET ;ALWAYS
;
; Uses: T1-T6
FREMSG: SKIPN T1,MB ;GET POINTER TO MESSAGE BLOCK
BUG.(CHK,ROUZXT,ROUTER,SOFT,<Tried to free msg with MB=0>,,<
Cause: This BUG is not documented yet.
>,RTN)
TMNE RMODN,(MB) ;DOES NSP WANT THIS BACK?
CALLRET R2NODN ;YES, GO GIVE "OUTPUT DONE"
;NO, GIVE MSG TO MEMORY MANAGER
TRASH MB, ;JUST CAREFUL
CALLRET DNFMSG ;FREE MESSAGE T1 POINTS TO
SUBTTL Miscellaneous Routines -- CKSNRM - Normalize Checksum
;CKSNRM - Make full word checksum into 16 bit checksum
;
; Call:
; T1/ Full word checksum
;
; Return:
; RET ;WITH T1 CONTAINING THE 16 BIT CHECKSUM
;
; Uses: T1-T2
CKSNRM: MOVE T2,T1 ;GET A COPY OF THE CHECKSUM
TDZE T2,[EXP ^-177777] ;IF ANY OVERFLOW, CLEAR IT
JRST [LSH T1,-^D16 ;ADD OVERFLOW BACK INTO
ADDB T2,T1 ; THE LOW ORDER BYTES
JRST .-1] ;LOOP UNTIL DONE
RET ;RETURN
SUBTTL Local Router Storage
$LOW ;IMPURE STORAGE
RTRNRV::BLOCK 1 ;"NORMAL" ROUTING VECTOR
RTRNOV::BLOCK 1 ;"NORMAL" OUTPUT-CIRCUIT VECTOR
RTROFS::BLOCK 1 ;OFFSET FROM NRV TO NOV
RTRSRV: BLOCK 1 ;"SCRATCH" ROUTING VECTOR
RTRSOV: BLOCK 1 ;"SCRATCH" OUTPUT-CIRCUIT VECTOR
RTRNTV: BLOCK 1 ;NODE TYPE VECTOR
RTRMXN::%RTMXN ;MAXIMUM NODE NUMBER
RTRCBQ::BLOCK QH.LEN ;CIRCUIT BLOCK QUEUE HEADER
RTRNLN::BLOCK 1 ;NUMBER OF CIRCUITS IN USE
RTRMXC::%RTMXC ;MAXIMUM CIRCUIT COST
RTRMXH::%RTMXH ;MAXIMUM HOPS
RTRMXV::%RTMXV ;MAXIMUM VISITS
RTRRCF: BLOCK 1 ;RECOMPUTE ROUTING FLAG
RTRVRQ::BLOCK 1 ;VERIFICATION REQUIRED FLAG
IFN FTOPS10,RTRADR::%RTADR ;OUR LOCAL ADDRESS
IFN FTOPS20,RTRADR::EXP 0 ;OUR LOCAL ADDRESS, SET AT RUN TIME
RTRCKS: BLOCK 1 ;CHECKSUM OF ROUTING MESSAGE
RTRTYP::EXP 0 ;OUR TYPE OF NODE IS ROUTING.
RTRTM1::%RTTM1 ;"SHORT" TIMER
RTRITM::%RTITM ;MAX TIME ALLOWED FROM PROTOCOL UP AND TI RCVD
RTRBSZ::%RTBSZ ;OUR BLOCKSIZE
RTRVER::%RTVER ;VERSION OF OUR ROUTER
RTRECO::%RTECO ;EDIT LEVEL OF RTR
RTRCUS::%RTCUS ;CUSTOMER ARGUMENT
RTRRSQ: BLOCK QH.LEN ;RESEND QUEUE HEADER
RTRSSV: BLOCK 1 ;ONCE-A-SEC SERVICE NEEDED FLAG
RTREVW: BLOCK 1 ;EVENT WORD (PLACE TO KEEP REASON, NODE, ETC.)
;[**FIX THIS**]. THIS CAN'T BE AN UNINTERLOCKED
;[**FIX THIS**] WORD. MOVE TO STACK.
;NODE COUNTERS:
RTRCAP::BLOCK 1 ; (900) AGED PACKET LOSS
RTRCNU::BLOCK 1 ; (901) NODE UNREACHABLE PACKET LOSS
RTRCNO::BLOCK 1 ; (902) NODE OUT-OF-RANGE PACKET LOSS
RTRCOP::BLOCK 1 ; (903) OVERSIZED PACKET LOSS
RTRCPF::BLOCK 1 ; (910) PACKET FORMAT ERROR
RTRCPR::BLOCK 1 ; (920) PARTIAL ROUTING UPDATE LOSS
RTRCVR::BLOCK 1 ; (930) VERIFICATION REJECT
$HIGH ;BACK TO THE PURE SEGMENT
SUBTTL End of ROUTER
IFN FTOPS10, .XCMSY ;.XCREF SOME MACSYM SYMBOLS
IFN FTOPS20, TNXEND ;TOPS-20 ENDING
END