📄 rricirc.c
字号:
sc = tc; } /* next hash bin */ break; } } } *link_after = sc; if (sid == (MAX_CIRCUIT + 1)) { return (0); } else { return (sid); }}/**************************************************ipCircEvent:a circuit signals the engine of an operational statechange or other event.Reference: utility*************************************************/void ipCircEvent(icirc_pt c, int event, void *param){ int i, old_state; ipna_pt loc_ipa; iproute_ent_pt iprt; /* SNAD Broadcast; rripa bcadd; */ IPNA my_rt; switch (event) { case RCEVENT_STATE: old_state = c->rc_state; /* only set to on if admin state is also on */ if (c->rc_admst == RCIRC_UP) { c->rc_state = *(int *) param; } else { c->rc_state = RCIRC_DOWN; } /* look for change */ if (c->rc_state == old_state) { return; } if (c->rc_state == RCIRC_UP) { loc_ipa = c->rc_ipa; /* add local route for each multi-homed addr */ /* NOTE: Comment in ipCircSetIPA seems to indicate that this loop is for naught since the code no longer supports multiple IP addresses per circuit (multi-homing). Apparently more than one circuit will be required! */ for (i = 0; i < MAX_IF_IPADD; i++, loc_ipa++) { if (!loc_ipa->ip_add) { break; } ipAddRoute(loc_ipa, loc_ipa->ip_add, c->rc_id, 1, IPRT_LOCAL, (rripa) 0);#if 0 /************** Not used for now *****************/ if (c->rc_type & RCIRC_LAN) { /* I/F addr */#ifdef IP_VLAN arpadd(loc_ipa->ip_add, &c->rc_ladd, c->rc_id, 0, ARP_LOC);#else arpadd(loc_ipa->ip_add, &c->rc_ladd, c->rc_id, ARP_LOC);#endif /* make broadcast addr */ Broadcast.s_type = SN_LAN; Broadcast.s_len = 6; ipFillMem(&Broadcast.s_addr, (char )0xff, 6); bcadd = loc_ipa->ip_add & loc_ipa->ip_mask;#ifdef IP_VLAN arpadd(bcadd, &Broadcast, c->rc_id, 0, ARP_LOC | ARP_BCAST);#else arpadd(bcadd, &Broadcast, c->rc_id, ARP_LOC | ARP_BCAST);#endif bcadd |= ~loc_ipa->ip_mask;#ifdef IP_VLAN arpadd(bcadd, &Broadcast, c->rc_id, 0, ARP_LOC | ARP_BCAST);#else arpadd(bcadd, &Broadcast, c->rc_id, ARP_LOC | ARP_BCAST);#endif } else { /* we need to know ipaddress of "us" on ptpt links too so we know whats for us and whats not. */ Broadcast.s_type = SN_PTPT; Broadcast.s_len = 0;#ifdef IP_VLAN arpadd(loc_ipa->ip_add, &Broadcast, c->rc_id, 0, ARP_LOC | ARP_PTPT);#else arpadd(loc_ipa->ip_add, &Broadcast, c->rc_id, ARP_LOC | ARP_PTPT);#endif }#endif /************** NOT USED ***************/ } /* send a router discovery advert */ /* Done in Fusion IcmpTxRtrDiscAdv(0xffffffff, c->rc_id); */#ifdef IPMULTI /* send an igmp query */ IgmpCircUp(c);#endif /* turn on static routes pointing here */ ipStaticRtOn(c->rc_id); } else { /* circ down */ loc_ipa = c->rc_ipa; /* del local route for each multi-homed addr */ for (i = 0; i < MAX_IF_IPADD; i++, loc_ipa++) { if (!loc_ipa->ip_add) { break; } my_rt.ip_add = loc_ipa->ip_add & loc_ipa->ip_mask; my_rt.ip_mask = loc_ipa->ip_mask; if ((iprt = ipFindRoute(&my_rt, IPRT_LOCAL)) != 0) { ipDelRoute(iprt); } }#ifdef IPMULTI /* stop igmp query */ IgmpCircDown(c);#endif /* turn off static routes pointing here */ ipStaticRtOff(c->rc_id);#ifdef P2_IP /* del arp entries */ /* I/F addr */ arppurge(c->rc_id);#endif }#if defined(RIP_PROTOCOL) ripCircEvent(c->rc_id, RCEVENT_STATE, (void *) &c->rc_state, (void *) &c->rc_ipa[0]);#endif#ifdef RR_DVMRP if (c->rc_mcastprot == IPMC_OWN_DVMRP){ dvmrpCircEvent(c->rc_id, RCEVENT_STATE, (void *) &c->rc_state, (void *) &c->rc_ipa[0]); }#endif#ifdef OSPF_PROTOCOL ospfCircEvent( (void *)c->rc_id, RCEVENT_STATE,(void *) &c->rc_state, (void *) &c->rc_ipa[0]);#endif#ifdef RR_PIM if (c->rc_mcastprot == IPMC_OWN_PIMDM || c->rc_mcastprot == IPMC_OWN_PIMSM || c->rc_mcastprot == IPMC_OWN_PIMV1){ pimCircEvent(c->rc_id, RCEVENT_STATE, (void *) &c->rc_state, (void *) &c->rc_ipa[0]); }#endif break; default: break; }}/**********************************************************ipCircEnable:Enable broadcast or PTPT circuit. May have already beencalled without intervening ipCircDisable().Calls iDLStart.**********************************************************/int ipCircEnable(icirc_pt c){ /* must have at least one address unless ptpt */ if (!c->rc_ipa->ip_add) { if (c->rc_type & RCIRC_LAN) return (-1); /* its an unnumbered line, force mask = all1 */ c->rc_ipa->ip_mask = 0xffffffff; } /* admin state on */ c->rc_admst = RCIRC_UP; /* What we want to do here is map this to a Fusion function to bring up the physical interface and if its successful it will call the circuit UP event!!! Cool. */ /* iDLStart(c); */ return (0);}/*********************************************************ipCircDisable:Disable broadcast or PTPT circuit.Call xDLStop.*********************************************************/void ipCircDisable(icirc_pt c){ if (c->rc_admst == RCIRC_DOWN) return;#if defined(RIP_PROTOCOL) { ipna_pt loc_ipa; int i; /* send update out circ saying everything unreachable via us. (for each multi-home) */ loc_ipa = c->rc_ipa; for (i = 0; i < MAX_IF_IPADD; i++, loc_ipa++) { if (!loc_ipa->ip_add) { break; } riptx(loc_ipa, c->rc_id, 0, (rripa) 0, 0, 1); } }#endif /* RIP_PROTOCOL */ c->rc_admst = RCIRC_DOWN; /* iDLStop(c); */}#ifdef IP_VLAN/***************************************************ipCircAddIFID:add phy port to circuit. Must be lan circ withsame mac addr and mtu.***************************************************/int ipCircAddIFID(icirc_pt c, int ifid){ /* cannot be PTPT */ if (!(c->rc_type & RCIRC_LAN)) { return (-1); } if (ifid < 0 || ifid > MAX_IFID) return (-1); if (RRMSK_CIS_SET(&ipL2PPortMap[c->rc_id], ifid)) return (0); /* update the log to phy mask */ RRMSK_CSET(&ipL2PPortMap[c->rc_id], ifid); /* update phy to log mask */ if (ipP2LPortMap[ifid] != 0) { ipP2LPortMap[ifid] = -1; /* must enforce only 1 igmp per if */ c->rc_mcastenl = 0; } else ipP2LPortMap[ifid] = c->rc_id; /* restart circ for many reasons */ if (c->rc_admst == RCIRC_UP) { ipCircDisable(c); ipCircEnable(c); } return (0);}/***************************************************ipCircDelIFID:delete phy port from circuit. if mask empty, deletecircuit.***************************************************/int ipCircDelIFID(icirc_pt c, int ifid){ int nonempty, done, i; icirc_pt sc, tc; if (ifid < 0 || ifid > MAX_IFID) return (-1); if (!RRMSK_CIS_SET(&ipL2PPortMap[c->rc_id], ifid)) return (-1); /* update the phy to log map */ if (ipP2LPortMap[ifid] == c->rc_id) ipP2LPortMap[ifid] = 0; else if (ipP2LPortMap[ifid] == -1) { /* is there one or more remaining circs using this port? */ for (i = 0; i < CIRC_HASHES; i++) { for (tc = (icirc_pt) ip_circ_hash[i].dll_fwd; tc; tc = tc->rc_fwd) { if (tc == c) continue; if (RRMSK_CIS_SET( &ipL2PPortMap[tc->rc_id], ifid)) { /* still more than one circ using phy port */ if (sc) { ipP2LPortMap[ifid] = -1; done = 1; break; } sc = tc; } if (done) break; } } /* physical to logical port map */ if (!done) { ASSERT(sc, "ipP2LPortMap corrupt"); /* 1 or 0 with same ifid */ ipP2LPortMap[ifid] = sc->rc_id; } } else ASSERT(0, "ipP2LPortMap corrupt"); /* update the log to phy mask */ RRMSK_CCLR(&ipL2PPortMap[c->rc_id], ifid); /* is it now empty? */ RRMSK_EMPTY_TEST(&ipL2PPortMap[c->rc_id], nonempty); if (nonempty) { /* restart circ for many reasons */ if (c->rc_admst == RCIRC_UP) { ipCircDisable(c); ipCircEnable(c); } } else { /* restart circ for many reasons */ if (c->rc_admst == RCIRC_UP) { ipCircDisable(c); } ipCircDelete(c->rc_id); } return (0);}#endif /* IP_VLAN *//*******************************************************ipCircuitState:read circuit state from another thread. performed underresource control.******************************************************/int ipCircuitState(int cid){ icirc_pt c; int state; use_critical; critical; c = ipCircFromId(cid); if(!c){ state = -1; } else{ state = c->rc_state; } normal; return(state);}/***********************************ipIntfMtu:finds mtu of given circ.**********************************/int ipIntfMtu(int cid){ icirc_pt c; int mtu; use_critical; critical; c = ipCircFromId(cid); if(!c){ mtu = 0; } else{ mtu = c->rc_maxlen; } normal; return(mtu);}fnc_prot(arpent_pt, IpGetNextHop, (byte *,int *, int ))/* * See if the given IP address is best reachable * via this ciruit. * */icirc_pt ipGetMatchAddr(icirc_pt c, rripa next){ int cid; if (!c->rc_ipa->ip_add) { return (icirc_pt)0; } IpGetNextHop((byte *)&next, &cid, 0 ); if( cid != INVALID_CIRC ) { if( c == ipCircFromId(cid) ) return c; else return (icirc_pt)0; }else return (icirc_pt)0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -