⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bgp.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 5 页
字号:
				 __FUNCTION__,				 ip6str(&wdrte->rt_ripinfo.rip6_dest, 0),				 wdrte->rt_ripinfo.rip6_plen,				 bgp_peerstr(bnp));#endif 			  bnp->rp_adj_ribs_in 				  = rte_remove(drte, bnp->rp_adj_ribs_in);		  }	  } else { /* RTE not found */		  syslog(LOG_NOTICE,			 "<%s>: MP_UNREACH_NLRI %s/%d: %s not origin (ignored): ",			 __FUNCTION__,			 ip6str(&wdrte->rt_ripinfo.rip6_dest, 0),			 wdrte->rt_ripinfo.rip6_plen,			 bgp_peerstr(bnp));	  }  }  if (uprtehead.rt_next != &uprtehead) {	  struct rt_entry *head = uprtehead.rt_next;	  remque(&uprtehead); 	/* XXX: uprtehead would annoy redistribute() */	  redistribute(head);	  insque(&uprtehead, head); /* XXX: restore link */	  if (!bgp_rpcb_isvalid(bnp)) {		  syslog(LOG_NOTICE,			 "<%s>: rpcb %p was invalidated during a redistribution",			 __FUNCTION__, bnp);		  goto done;	  }  } /* uprtehead */  task_timer_update(bnp->rp_hold_timer);  done:    if (asp)	    free_aspath(asp);    {	    struct rt_entry *drte;	    for (drte = uprtehead.rt_next; drte != &uprtehead;) {		    struct rt_entry *nrte = drte->rt_next;		    remque(drte);		    free(drte);	/* aspath has been already freed. */		    drte = nrte;	    }	    for (drte = wdrtehead.rt_next; drte != &wdrtehead;) {		    struct rt_entry *nrte = drte->rt_next;		    remque(drte);		    free(drte);	/* ditto. */		    drte = nrte;	    }    }  /* End of bgp_process_update() */}static intbgp_selectroute(rte, bnp)	struct rt_entry *rte;	struct rpcb *bnp;{	struct rpcb     *obnp;      /* search for */	struct rt_entry *orte;	extern struct ripif    *ripifs;	extern byte             ripyes; 	/*	 * At first, check our own routes since possible propagation	 * might destory bnp...Ugh!	 */	if ((orte = find_rte(rte, bnp->rp_adj_ribs_in))) {		struct rt_entry crte; /* local copy */		/*		 * i) If its Network Layer Reachability Information (NLRI)		 * is identical to the one of a route currently stored		 * in the Adj-RIB-In, then the new route shall replace the		 * older route in the Adj-RIB-In, thus implicitly withdrawing		 * the older route from service. The BGP speaker shall run		 * its Decision Process since the older route is no longer		 * available for use.		 * [BGP4+   9. UPDATE Message Handling]		 */		if (orte->rt_flags & RTF_UP) {#ifdef DEBUG_BGP			syslog(LOG_NOTICE,			       "<%s>: %s/%d from %s was overwritten "			       "nexthop=(old:%s, new:%s)",			       __FUNCTION__,			       ip6str(&orte->rt_ripinfo.rip6_dest, 0),			       orte->rt_ripinfo.rip6_plen,			       bgp_peerstr(bnp),			       ip6str(&orte->rt_bgw, 0),			       ip6str(&rte->rt_bgw, 0));#endif 			crte = *orte;			crte.rt_next = crte.rt_prev = &crte;			bgp_disable_rte(&crte);			propagate(&crte);			/* XXX: propagate might invalidate bnp */			if (!bgp_rpcb_isvalid(bnp)) {				syslog(LOG_NOTICE,				       "<%s>: rpcb %p was invalidated during a "				       "propagation", __FUNCTION__, bnp);				return(-1);			}		}		bnp->rp_adj_ribs_in = rte_remove(orte,						 bnp->rp_adj_ribs_in);	}	obnp = bgb;	while(obnp) {		if (bnp != obnp && /* already done above */		    (orte = find_rte(rte, obnp->rp_adj_ribs_in))) {			/* same NLRI */			/*			 * Route Selection			 * take care of route flapping !!			 * comparison technique			 * (like RIPng metric) (1998/05/13)			 */			if (orte->rt_flags & RTF_UP) {				if (bgp_preferred_rte(rte, orte)) {					/* a new RTE may prefer */					bgp_disable_rte(orte);					orte->rt_flags &= ~RTF_UP;				}				else {					/*					 * Don't activate Kernel table					 */					rte->rt_flags &= ~RTF_UP;					IFLOG(LOG_BGPINPUT)					  syslog(LOG_DEBUG,						 "<%s>: to be backup.",						 __FUNCTION__);				}			}		}		if ((obnp = obnp->rp_next) == bgb) 			break;	} /* End of while(obnp) */	/**  check RIPng routes  **/	if (ripyes) {		struct ripif *oripif;		oripif = ripifs;		while(oripif) {			/* iw97 */			if ((orte = find_rte(rte, oripif->rip_adj_ribs_in)) &&			    (orte->rt_flags & RTF_UP)) {				/* fuckin' reversing BGP speker */				/* route synchronization(1998/06/20) */				if (orte->rt_ripinfo.rip6_tag == 0) {					/* purely internal */					/*					 * Don't activate Kernel table					 */					rte->rt_flags &= ~RTF_UP;					break; /* while(oripif) */				}				if (bnp->rp_mode & BGPO_IGP){					/* IBGP */					if (rte->rt_ripinfo.rip6_tag ==					    orte->rt_ripinfo.rip6_tag){						struct rt_entry *nrte;						/*						 * If "rte" is backup, don't						 * install even if "rte"						 * becomes syncronized						 */						IFLOG(LOG_BGPINPUT)						  syslog(LOG_DEBUG,							 "<%s>: now synchronized.", __FUNCTION__);						nrte = rip_disable_rte(orte);						free(nrte);						rte->rt_flags |=							RTF_IGP_EGP_SYNC;						orte->rt_flags |=							RTF_IGP_EGP_SYNC;					} else {  /* tag differ */						if (orte->rt_flags & RTF_IGP_EGP_SYNC &&						    rte->rt_flags & RTF_UP) {						  IFLOG(LOG_BGPINPUT)						    syslog(LOG_DEBUG,							   "<%s>: a new iBGP RTE prefered.",							   __FUNCTION__);							rip_erase_rte(orte);						}					}				} else {    /* eBGP */					if (rte->rt_ripinfo.rip6_tag ==					    orte->rt_ripinfo.rip6_tag) {						IFLOG(LOG_BGPINPUT)							syslog(LOG_DEBUG,							       "<%s>: fear.",							       __FUNCTION__);						rip_erase_rte(orte);					} else {  /* tag differ */						if (orte->rt_flags & RTF_IGP_EGP_SYNC &&						    rte->rt_flags & RTF_UP) {							syslog(LOG_NOTICE, "<%s>: a new eBGP RTE prefered.",							       __FUNCTION__);							rip_erase_rte(orte);						} else {							IFLOG(LOG_BGPINPUT)								syslog(LOG_DEBUG, "<%s>: to be Backup.", __FUNCTION__);	/* XXX long... */							rte->rt_flags &= ~RTF_UP;						}					}				} /* End of eBGP */ 			}			/* still I may get poison-reverse via RIP */			if ((oripif = oripif->rip_next) == ripifs)				break;		}  /* while(oripif) */	} /* (ripyes) */	return(0);		/* sucess */}/* *    bgp_process_notification() *       process received KEEPALIVE msg. */voidbgp_process_notification (struct rpcb *bnp) {  char         in6txt[INET6_ADDRSTRLEN];  struct bgphdr *bh = (struct bgphdr *)bnp->rp_inpkt;  extern char *bgp_errstr[];  extern char *bgp_hdrerrstr[];  extern char *bgp_opnerrstr[];  extern char *bgp_upderrstr[];  memset(in6txt, 0, INET6_ADDRSTRLEN);  syslog(LOG_NOTICE,	 "NOTIFICATION received from %s (%s AS %d): code %d (%s) data %s",	 inet_ntop(AF_INET6, &bnp->rp_addr.sin6_addr,		   in6txt, INET6_ADDRSTRLEN),	 ((bnp->rp_mode & BGPO_IGP) ? "Internal" : "External"),	 (int)bnp->rp_as,	 (int)bnp->rp_inpkt[BGP_HEADER_LEN],   /* code */	 bgp_errstr[(int)bnp->rp_inpkt[BGP_HEADER_LEN]],	 bgp_errdatastr(&bnp->rp_inpkt[BGP_HEADER_LEN + 2],			ntohs(bh->bh_length) - (BGP_HEADER_LEN + 2)));  switch ((int)bnp->rp_inpkt[BGP_HEADER_LEN]) { /* code */  case BGP_ERR_HEADER:    if ((int)bnp->rp_inpkt[BGP_HEADER_LEN+1] <= BGP_ERRHDR_TYPE)      syslog(LOG_NOTICE, "\t subcode (%d) %s",	     (int)bnp->rp_inpkt[BGP_HEADER_LEN+1],	     bgp_hdrerrstr[(int)bnp->rp_inpkt[BGP_HEADER_LEN+1]]);    break;  case BGP_ERR_OPEN:    if ((int)bnp->rp_inpkt[BGP_HEADER_LEN+1] <= BGP_ERROPN_BADHOLDTIME)      syslog(LOG_NOTICE, "\t subcode (%d) %s",	     (int)bnp->rp_inpkt[BGP_HEADER_LEN+1],	     bgp_opnerrstr[(int)bnp->rp_inpkt[BGP_HEADER_LEN+1]]);    break;  case BGP_ERR_UPDATE:    if ((int)bnp->rp_inpkt[BGP_HEADER_LEN+1] <= BGP_ERRUPD_ASPATH)      syslog(LOG_NOTICE, "\t subcode (%d) %s",	     (int)bnp->rp_inpkt[BGP_HEADER_LEN+1],	     bgp_upderrstr[(int)bnp->rp_inpkt[BGP_HEADER_LEN+1]]);    break;  default:    break;  }  /* Update Hold Timer. XXX: connection will soon be released */  if (bnp->rp_state == BGPSTATE_ESTABLISHED)	  task_timer_update(bnp->rp_hold_timer);  bgp_cease(bnp);  /* no means of reporting error in NOTIFICATION msg */}/* *    bgp_process_keepalive() *       process received KEEPALIVE msg. */voidbgp_process_keepalive (struct rpcb *bnp){  int                    i;               /*  tracer       */  struct bgphdr          *bh;  struct rt_entry        *rtehead, *rte;  /*  advertising  */  rtehead = rte = NULL;  bh = (struct bgphdr *)bnp->rp_inpkt;  BGP_MARKER_CHECK;  switch (bnp->rp_state) {  case BGPSTATE_OPENCONFIRM:    bnp->rp_state = BGPSTATE_ESTABLISHED;    IFLOG(LOG_BGPSTATE)	    syslog(LOG_NOTICE,		   "<%s>: BGP state shift[%s] peer: %s", __FUNCTION__,		   bgp_statestr[bnp->rp_state], bgp_peerstr(bnp));    if (bgpsbsize &&	setsockopt(bnp->rp_socket, SOL_SOCKET, SO_SNDBUF, &bgpsbsize,		   sizeof(bgpsbsize)) < 0) {	    fatal("bgp_process_keepalive>: setsockopt");    }    bgp_update_stat(bnp, BGPS_ESTABLISHED);    bgp_dump(bnp);    if (bnp && bnp->rp_hold_timer)      task_timer_update(bnp->rp_hold_timer);    break;  case BGPSTATE_ESTABLISHED:    task_timer_update(bnp->rp_hold_timer);    break;  default:    bgp_notify(bnp, BGP_ERR_FSM, BGP_ERR_UNSPEC, 0, NULL);    break;  };}/* *    collision_resolv() */struct rpcb *collision_resolv(newconn, oldconn)     struct rpcb *newconn;     struct rpcb *oldconn;{  IFLOG(LOG_BGPSTATE)    syslog(LOG_DEBUG, "<collision_resolv>: invoked.");  if (newconn->rp_id > bgpIdentifier) {    bgp_notify(oldconn, BGP_CEASE, BGP_ERR_UNSPEC, 0, NULL); /* use newconn */    return newconn;  } else {    bgp_notify(newconn, BGP_CEASE, BGP_ERR_UNSPEC, 0, NULL); /* use oldconn */     return oldconn;    }   IFLOG(LOG_BGPSTATE)    syslog(LOG_DEBUG, "<collision_resolv>: end.");}/* *  bgp_holdtimer_expired() */voidbgp_holdtimer_expired(task *t){  IFLOG(LOG_BGPSTATE)    syslog(LOG_DEBUG,	   "<%s>: holdtime expired for %s (%s AS %d)",	   __FUNCTION__,	   ip6str2(&t->tsk_bgp->rp_addr),	   ((t->tsk_bgp->rp_mode & BGPO_IGP) ? "Internal" : "External"),	   (int)t->tsk_bgp->rp_as);  bgp_notify(t->tsk_bgp, BGP_ERR_HOLDTIME, BGP_ERR_UNSPEC, 0, NULL);}/* *   bgp_notify() */voidbgp_notify(struct rpcb *bnp, byte errcode, byte subcode, int len, byte *data){  bgp_send_notification(bnp, errcode, subcode, len, data);  bgp_cease(bnp);}/* *   bgp_cease() */voidbgp_cease(struct rpcb *bnp){  struct rpcb     *abnp = NULL;                 /* another entry */  if (bnp == NULL)    return;  bgp_flush(bnp);#if 0  /* XXX: ad-hoc solution */  abnp = bgb;  while(abnp) {    if (abnp != bnp &&	abnp->rp_state == BGPSTATE_ESTABLISHED)      bgp_dump(abnp);    if ((abnp = abnp->rp_next) == bgb)      break;  }#endif  /***  PASSIVEly opened Entry ***/  if (bnp->rp_mode & BGPO_PASSIVE) {       /*  Remove the Entry from global-list */    if (bgb->rp_next != bgb) { /* check solo ? */      if (bgb == bnp)	bgb = bgb->rp_next;      remque(bnp);    } else {   /* solo */      /* active entry should exist. */	          fatalx("bgp_cease: no active entry(BUG !!)");     }    /*     * If there is an RPCB whose state is IDLE for the peer and     * there is no other active peer, retry connecting to it     * (after waiting for ConnectRetryTimer).     * It must not be an already opened passive connection(should we check it?)     */    if (!find_active_peer(bnp) && (abnp = 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -