📄 rricirc.c
字号:
/** Copyright (c) 1998-2001 by NETsilicon Inc.** This software is copyrighted by and is the sole property of* NETsilicon. All rights, title, ownership, or other interests* in the software remain the property of NETsilicon. This* software may only be used in accordance with the corresponding* license agreement. Any unauthorized use, duplication, transmission,* distribution, or disclosure of this software is expressly forbidden.** This Copyright notice may not be removed or modified without prior* written consent of NETsilicon.** NETsilicon, reserves the right to modify this software* without notice.** NETsilicon* 411 Waverley Oaks Road USA 781.647.1234* Suite 227 http://www.netsilicon.com* Waltham, MA 02452 AmericaSales@netsilicon.com*************************************************************************** $Name: Fusion 6.52 Fusion 6.51 $* $Date: 2002/01/22 14:09:54 $* $Source: M:/psisrc/routing/rrfdb/rcs/rricirc.c $* $Revision: 1.7 $**************************************************************************** File Description: Circuit creation and deletion utilities for IP **************************************************************************/#include <riproute.h>#include <rrport.h>#include <icirc.h>#include "rripfdb.h"#ifdef OSPF_PROTOCOL#include "fnsrr.h"#endiffnc_prot(icirc_pt, ipCircFromId, (int))fnc_prot(void, ipCircDisable,(icirc_pt c))fnc_prot(iproute_ent_pt, ipFindRoute,(ipna_pt,int))fnc_prot(void, ipDelRoute,(iproute_ent_pt iprt))fnc_prot(int,ipCircFreeId,(icirc_pt * link_after))fnc_prot(int,ipCircEnable,(icirc_pt c))/*********************************************ipCircuitInit:initialize contents of newly createdcircuit struct.Reference: utility*********************************************/int ipCircuitInit(icirc_pt circuit, snad_pt ladd, int type, int maxlen, int if_id){ int cid = circuit->rc_id; ipFillMem((circuit), 0, sizeof(ICIRC)); circuit->rc_id = cid; /* logical to physical port map */ ipL2PPortMap[if_id] = circuit->rc_id; ipP2LPortMap[circuit->rc_id] = if_id; /* We don't currently make any use of the ladd parameter */ if( ladd != (snad_pt)0 ) { /* ladd is src for lan, dst for ptpt */ ipCopyMem((char *)&circuit->rc_ladd, ladd, sizeof(SNAD)); } circuit->rc_maxlen = maxlen; /* speeds up forwarding */ ipCircsMtu[cid] = maxlen; circuit->rc_type = type; /* speeds up multicast forwarding */ ipCircsType[cid] = type; circuit->rc_admst = RCIRC_DOWN; circuit->rc_state = RCIRC_DOWN; circuit->rc_arprsp = TRUE; /* only one on a port at a time */ circuit->rc_mcastenl = FALSE; circuit->rc_mcastprot = 1;#ifdef IPMULTI circuit->rc_igmp_version = IGMP_DEF_VERSION; circuit->rc_igmp_state = IGMP_ST_DOWN; circuit->rc_igmp_qint = IGMP_CDEF_QINT; circuit->rc_igmp_maxrsp = IGMP_CDEF_MAXRSP; circuit->rc_igmp_qptimeout = IGMP_CDEF_QPTIO; circuit->rc_igmp_leaveena = IGMP_CDEF_LEAVEENA; circuit->rc_igmp_v1qt = IGMP_CDEF_V1QT;#endif return (1);}/************************************************ipCircCreate:create a circuit.returns 0 or ptr to circuit structReference: utility************************************************/icirc_pt ipCircCreate(int type, snad_pt ladd, int maxlen, int if_id, int rcid, dword ifspeed){ icirc_pt circuit, sc; int si; if (i_node->rn_num_circ >= MAX_CIRCUIT) { return (0); } /* circ id must also be <= MAX_CIRCUIT */ if (rcid > MAX_CIRCUIT) { return (0); } if ((circuit = (icirc_pt) ipCircuitAlloc(sizeof(ICIRC))) == NULL) { return (0); } else { i_node->rn_num_circ++; /* get an available cid if one not requested */ if (rcid) { if (ipCircFromId(rcid)) { /* already used */ ipCircuitFree(circuit); return (0); } circuit->rc_id = rcid; sc = 0; } else { circuit->rc_id = ipCircFreeId(&sc); } /* initialize */ if (!ipCircuitInit(circuit, ladd, type, maxlen, if_id)) { ipCircuitFree(circuit); return (0); } /* link it to hash list */ si = circuit->rc_id & (CIRC_HASHES - 1); ipGenLink((dll_pt) circuit, (dll_pt) sc, (dll_pt) & ip_circ_hash[si]); } circuit->rc_tput = ifspeed; return (circuit);}/*********************************************ipCircSetIPA:Add an IP address to a circuit.We need to disable circ to do this.*********************************************/int ipCircSetIPA(icirc_pt c, ipna_pt ipna, void *magic){ int i, old_state; i = 0; old_state = c->rc_admst; if (old_state == RCIRC_UP) { ipCircDisable(c); } ipCopyMem(&c->rc_ipa[i], ipna, sizeof(IPNA)); /* used for ptpt, eg dlci. NOTE: multihoming on single logical interface now deprecated */ c->rc_magic = magic; /* put circpt in map array for fast ifid to circ mapping. if member non-empty, put in -1 to indicate a multi-homed lookup is required. */ if (old_state == RCIRC_UP) { ipCircEnable(c); } return (0);}/********************************************ipCircDelete:deletes a circuit. The circuit must be in the OFFstate before deletion can take place.Reference: utility**********************************************/int ipCircDelete(int cid){ icirc_pt c, tc, sc; int i, done, ifid; if ((c = ipCircFromId(cid)) == 0) { return (-1); } if (c->rc_state != RCIRC_DOWN) { return (-1); } /* adjust phy to logical port map, if no other circ using port, set to 0, if still > 1 circ using port, set to -1, else set to id of circ */ sc = 0; done = 0; ifid = ipL2PPortMap[c->rc_id]; 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 (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) { /* 1 or 0 with same ifid */ ipP2LPortMap[ifid] = (sc) ? sc->rc_id : 0; }#ifdef IP_VLAN /* foreach port in vlan, adjust phy to log map */ for (ifid = 0; ifid <= MAX_IFID; ifid++) { if (!RRMSK_CIS_SET(&ipL2PPortMap[c->rc_id], ifid)) continue; 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 ifid is in tc's port mask */ 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) { /* 1 or 0 with same ifid */ ipP2LPortMap[ifid] = (sc) ? sc->rc_id : 0; } }#endif /* logical to physical port map */#ifdef IP_VLAN RRMSK_ALLCLR(&ipL2PPortMap[c->rc_id]);#else ipL2PPortMap[c->rc_id] = 0;#endif#if defined(RIP_PROTOCOL) /* free associated circs */ ripCircDelete(c->rc_id);#endif#ifdef RR_DVMRP dvmrpCircDelete(c->rc_id);#endif#ifdef RR_PIM pimCircDelete(c->rc_id);#endif /* free the circuit itself */ ipULink((dll_pt) c, (dll_pt) & ip_circ_hash[c->rc_id & (CIRC_HASHES - 1)].dll_fwd);#ifndef IP_VLAN#ifdef IPMULTI /* if does igmp, look for another to replace it */ if (c->rc_mcastenl) { xc = ipCircFromIFID(ifid); if (xc) igmpCircEnable(xc->rc_id); }#endif#endif i_node->rn_num_circ--; ipCircuitFree(c); return (0);}/*****************************************ipCircFromId: returns circuit ptr with specified idReference: utility********************************************/icirc_pt ipCircFromId(int id){ int i, index; icirc_pt c; /* go through the hash list */ index = id & (CIRC_HASHES - 1); for (i = 0, c = (icirc_pt) ip_circ_hash[index].dll_fwd; i < MAX_CIRCUIT && c; i++, c = c->rc_fwd) { if (c->rc_id == id) { return (c); } } return (0);}/**********************************************ipCircFromIFID:locates circ from ifif, NOT id. Used only forlans. called to find any circ when ip srcaddr = 0. note that it is primarily used foraddr mask req.*********************************************/icirc_pt ipCircFromIFID(int id){ int i; icirc_pt c, maybe = 0; for (i = 0; i < CIRC_HASHES; i++) { for (c = (icirc_pt) ip_circ_hash[i].dll_fwd; c; c = c->rc_fwd) { if (!(c->rc_type & RCIRC_LAN)) continue;#ifdef IP_VLAN if (RRMSK_CIS_SET(&ipL2PPortMap[c->rc_id], id)) {#else if (ipL2PPortMap[c->rc_id] == id) {#endif /* we prefer one with multicasting enabled */ if (c->rc_mcastenl) { return (c); } maybe = c; } } } return ((icirc_pt) maybe);}/******************************************ipCircNextId:gets next greater used id value.used primarily by snmp getnext.Reference: utility******************************************/int ipCircNextId(int old_id){ int next_id = MAX_CIRCUIT + 1; int i; icirc_pt c; /* go through hash list */ for (i = 0; i < CIRC_HASHES; i++) { for (c = (icirc_pt) ip_circ_hash[i].dll_fwd; c; c = c->rc_fwd) { /* see if this ID is lower than last suspect */ if ((c->rc_id > old_id) && (c->rc_id < next_id)) { next_id = c->rc_id; } } } if (next_id < MAX_CIRCUIT + 1) { return (next_id); } else { return (0); }}/*********************************************************ipCircFreeId:gets the lowest unused circuit id.returns 0 on none free.Reference: utility*********************************************************/int ipCircFreeId(icirc_pt * link_after){ icirc_pt tc; int i, sid = MAX_CIRCUIT + 1; icirc_pt sc = 0; /* find lowest available circ_id */ for (i = 0; i < CIRC_HASHES; i++) { /* hash bin is empty */ if ((tc = (icirc_pt) ip_circ_hash[i].dll_fwd) == 0) { /* NOTE: 0 is not used, first index in bin 0 is CIRC_HASHES */ if (i) { sid = i; /* done, no need to check further */ break; } else { sid = CIRC_HASHES; } /* next bin */ continue; } /* bin 0 and first in bin not lowest possible */ if (!i && (tc->rc_id != CIRC_HASHES)) { sid = CIRC_HASHES; sc = (icirc_pt) & ip_circ_hash[i].dll_fwd; continue; } /* bin !=0 and first in bin not lowest possible */ if (i && (tc->rc_id != i)) { sid = i; sc = (icirc_pt) & ip_circ_hash[i].dll_fwd; /* no need to check further */ break; } /* bin has lowest possbile in first entry */ for (; tc; tc = tc->rc_fwd) { if (!tc->rc_fwd || (tc->rc_fwd->rc_id != (tc->rc_id + CIRC_HASHES))) { /* end of bin or hole in bin */ if (tc->rc_id + CIRC_HASHES < sid) { sid = tc->rc_id + CIRC_HASHES;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -