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

📄 bgp.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	  syslog(LOG_NOTICE,		 "<%s>: Invalid prefix(%s/%d) in NLRI (ignored) from %s",		 __FUNCTION__,		 ip6str(&rte->rt_ripinfo.rip6_dest, 0),		 rte->rt_ripinfo.rip6_plen, bgp_peerstr(bnp));	  free(rte);	  continue;  /* to next rte */	}	if (bgp_input_filter(bnp, rte)) {	  if ((logflags & LOG_BGPINPUT))	    syslog(LOG_DEBUG, "<%s>: NLRI %s/%d from %s was filtered",		   __FUNCTION__,		   ip6str(&rte->rt_ripinfo.rip6_dest, 0),		   rte->rt_ripinfo.rip6_plen, bgp_peerstr(bnp));	  free(rte);	  continue;		/* to next rte */	}		if (rte->rt_ripinfo.rip6_plen == 128) {	  ife = ifentry;	  while(ife) {	    /*  check global I/F addrs  */	    if (IN6_ARE_ADDR_EQUAL(&rte->rt_ripinfo.rip6_dest,				   &ife->ifi_gaddr)) {	      ife = NULL;	      break;	    }	    if ((ife = ife->ifi_next) == ifentry)	      break;	  }	  if (ife == NULL) {	    free(rte);	    continue;  /* ignore */		  }	}	/*	 * XXX: A link-local next hop is sometimes more useful than global one,	 * but we can't trust that it's really on a link that we connect with,	 *so we always use a global next hop for safety...	 */	rte->rt_bgw = gnhaddr;	rte->rt_flags = RTF_UP|RTF_GATEWAY;	if (rte->rt_ripinfo.rip6_plen == 128)	  rte->rt_flags |= RTF_HOST;	rte->rt_ripinfo.rip6_tag    = htons(aspath2tag(asp));	rte->rt_ripinfo.rip6_metric = 0;   /* (ad-hoc) */	rte->rt_proto.rtp_type      = RTPROTO_BGP;	rte->rt_proto.rtp_bgp       = bnp; /* for each RTE, each RTP exists. */	rte->rt_aspath = asp; /* AS path field will be filled in later */	/*  check I/F routes  */	ife = ifentry;	while(ife) {	  if ((orte = find_rte(rte, ife->ifi_rte)))	    break;	  if ((ife = ife->ifi_next) == ifentry)	    break;	}	if (orte != NULL) {  /* I/F direct route (most preferable) */	  if ((logflags & LOG_BGPINPUT))	    syslog(LOG_DEBUG,		   "<%s>: I/F direct %s/%d not overwritten", __FUNCTION__,		   inet_ntop(AF_INET6, &rte->rt_ripinfo.rip6_dest, in6txt,			     INET6_ADDRSTRLEN),		   rte->rt_ripinfo.rip6_plen);	  free(rte);	  continue;  /* to next rte */	}	/*  check aggregate routes  */	if (find_rte(rte, aggregations)) {	  if ((logflags & LOG_BGPINPUT))	    syslog(LOG_DEBUG,		   "<%s>: aggregate route %s/%d cannot overwritten",		   __FUNCTION__,		   ip6str(&rte->rt_ripinfo.rip6_dest, 0),		   rte->rt_ripinfo.rip6_plen);	  free(rte);	  continue;  /* to next rte */	}	insque(rte, &uprtehead); /* Keep the RTE in the queue for later use */      }  /* End of while (NLRI) */      /* If an optional attribute is recognized, then the value of this	 attribute is checked.  If an error is detected, the attribute is	 discarded, and the Error Subcode is set to Optional Attribute Error.	 The Data field contains the attribute (type, length and value). */      if (i != k + atrlen) {	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_OPTATTR,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      break;    case PA4_TYPE_MPUNREACHNLRI:      /* MP_UNREACH_NLRI (Type Code 15) optional non-transitive */      /* An UPDATE message that contains the MP_UNREACH_NLRI is not required	 to carry any other path attributes.  */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	   (bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* Address Family Identifier            (2 octets) */      if (ntohs(*(u_int16_t *)&bnp->rp_inpkt[i]) != AFN_IP6) {	syslog(LOG_NOTICE,	       "<%s>: AFI is not AFN_IP6(%d)", __FUNCTION__, AFN_IP6);	i += atrdatalen;	break;   /* Gently ignore :-) */      }      i += 2;      /* SAFI */      /* Subsequent Address Family Identifier (1 octet) */      if (bnp->rp_inpkt[i++] != PA4_MP_UCAST) {      /* implmntd for UNIcast only */	syslog(LOG_NOTICE,	       "<%s>: SAFI isn't (%d). I only support unicast", __FUNCTION__,	       PA4_MP_UCAST);	i = k + atrlen;	break;    /* Quietly ignore :-< */      }#ifdef DRAFT_IETF_00      /* Unfeasible Routes Length (2 Octets) */      nlrilen = ntohs(*(u_short *)&bnp->rp_inpkt[i]);      i += 2;      if (i + nlrilen  !=  k + atrlen) {	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }#endif      /***  Withdrawn Routes  ( NLRI encoding )  ***/      while (i < k + atrlen) {             /* Malform is detected ASAP */	struct rt_entry *rte;	int              poctets;   /* (minimum len in octet bound) */	int first = 1;		/* XXX: just for statistics */	if (first) {	  bgp_update_stat(bnp, BGPS_WITHDRAWRCVD);	  first = 0;	}	MALLOC(rte, struct rt_entry);	/* Length in bits (1 octet) */	if ((rte->rt_ripinfo.rip6_plen = bnp->rp_inpkt[i++]) > 128) {	  syslog(LOG_NOTICE,		 "<%s>: Bad prefix length (=%d) in NLRI", __FUNCTION__,		 rte->rt_ripinfo.rip6_plen);	  free(rte);	  i = k + atrlen;	  break;   /* ignore  rest of MP_UNREACH_NLRI */	}	poctets = POCTETS(rte->rt_ripinfo.rip6_plen);	/* Dest. */	memcpy(rte->rt_ripinfo.rip6_dest.s6_addr, &bnp->rp_inpkt[i], poctets);	i += poctets;	if ((logflags & LOG_BGPINPUT))	  syslog(LOG_DEBUG, "BGP+ RECV\t\t%s/%d",		 ip6str(&rte->rt_ripinfo.rip6_dest, 0),		 rte->rt_ripinfo.rip6_plen);	if (!IN6_IS_ADDR_ROUTABLE(&rte->rt_ripinfo.rip6_dest)) {	  if ((logflags & LOG_BGPINPUT))	    syslog(LOG_DEBUG,		   "<%s>: Invalid prefix(%s/%d) in UNLRI (ignored) from %s",		   __FUNCTION__,		   ip6str(&rte->rt_ripinfo.rip6_dest, 0),		   rte->rt_ripinfo.rip6_plen, bgp_peerstr(bnp));	  free(rte);	  continue;  /* to next rte */	}	if (bgp_input_filter(bnp, rte)) {	  IFLOG(LOG_BGPINPUT)	    syslog(LOG_DEBUG, "<%s>: UNLRI %s/%d from %s was filtered",		   __FUNCTION__,		   ip6str(&rte->rt_ripinfo.rip6_dest, 0),		   rte->rt_ripinfo.rip6_plen, bgp_peerstr(bnp));	  free(rte);	  continue;		/* to next rte */	}	rte->rt_proto.rtp_type      = RTPROTO_BGP;	rte->rt_proto.rtp_bgp       = bnp; /* for each RTE, each RTP exists. */	rte->rt_aspath = asp; /* AS path field will be filled in later */	insque(rte, &wdrtehead);/* Keep the RTE in the queue for later use */      }  /* End of while(NLRI) */      break;    default:      /* XXX: PA propagation not fully implemented. */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      /* If any of the mandatory well-known attributes are not recognized,	 then the Error Subcode is set to Unrecognized Well-known Attribute.	 The Data field contains the unrecognized attribute (type, length and	 value). */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)) {	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_UNKNOWN,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }            /*       * Optional transitive attributes should be passed to other peers       * transparently.       */      if ((bnp->rp_inpkt[k] & PA_FLAG_OPT) &&	  (bnp->rp_inpkt[k] & PA_FLAG_TRANS)) {	IFLOG(LOG_BGPINPUT)	  syslog(LOG_DEBUG,		 "<%s>: BGP+ RECV\t\tUnrecognized Attribute: type=%d,len=%d",		 __FUNCTION__, bnp->rp_inpkt[k + 1], atrdatalen);	optatr = add_optatr(optatr, &bnp->rp_inpkt[k], atrlen);      }      /* optional non-transitive attributes the Partial bit must be	 set to 0. */      if (!(bnp->rp_inpkt[k] & PA_FLAG_TRANS)  &&	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL)) {   /* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* Unrecognized non-transitive optional attributes must be quietly	 ignored and not passed along to other BGP peers. [Page20]       */      /* V */      i += atrdatalen;      /* quietry ignore */      break;    }  /* <--  End of Switch path-attrs. */  }  if (pa_p + tpalen != i) {      /* Malformed Attribute List */    bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_ATTRLIST, 0, NULL);    goto done;  }  /* In IPv4 BGP4, here appears "traditional NLRI",       which can be quietry ignored in BGP4+ (for IPv6) */  if ((v4nlrilen = length - i ) > 0)    syslog(LOG_NOTICE,	   "<bgp_process_update>: traditional NLRI appread (ignore)");  { byte missin_attr = 0;    /* If any of the mandatory well-known attributes are not present, then       the Error Subcode is set to Missing Well-Known Attribute. The Data       field contains the Attribute Type Code of the missing well-known       attribute. */    if (!(bit_test(parsedflag, PA4_TYPE_ORIGIN)))      missin_attr = PA4_TYPE_ORIGIN;    if (!(bit_test(parsedflag, PA4_TYPE_ASPATH)))      missin_attr = PA4_TYPE_ASPATH;    if (!(bit_test(parsedflag, PA4_TYPE_MPREACHNLRI)) &&     /* bgp4+ */	!(bit_test(parsedflag, PA4_TYPE_NEXTHOP)))      missin_attr = PA4_TYPE_NEXTHOP;    if ((bnp->rp_mode & BGPO_IGP) &&	!(bit_test(parsedflag, PA4_TYPE_LOCALPREF)))      missin_attr = PA4_TYPE_LOCALPREF;    /* An UPDATE message that contains the MP_UNREACH_NLRI is not required       to carry any other path attributes. */    if (missin_attr &&	(v4nlrilen > 0 || !bit_test(parsedflag, PA4_TYPE_MPUNREACHNLRI))) {      bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_MISSING, 1, &missin_attr);      goto done;    }  }  /* missin_atr */  /*   * At this point, the received message is confirmed to be valid.   * Now install or redistribute routes according to the message.   */  if (asp) {    asp->asp_origin    = origin;    asp->asp_nexthop   = gnhaddr;    asp->asp_nexthop_local = lnhaddr; /* may be unspecified */    asp->asp_med       = med;            /* net  order      */    asp->asp_localpref = localpref;      /* net  order      */    asp->asp_atomagg   = aggregated;    asp->asp_origid    = originatorid;   /* net  order      */    asp->asp_clstr     = cll;    asp->asp_optatr    = optatr;  }  /***                     ***/  /***   Route Selection   ***/  /***                     ***/	/* XXX: protocol preference ?? */  for (uprte = uprtehead.rt_next; uprte != &uprtehead;       uprte = uprte->rt_next) {	  struct rt_entry *nrte = NULL;	  if (bgp_selectroute(uprte, bnp))		  goto done;	  if (bgp_enable_rte(uprte) == 0) {		  IFLOG(LOG_BGPINPUT)			  syslog(LOG_NOTICE,				 "<%s>: MP_REACH_NLRI %s/%d: from %s, "				 "not enabled",				 __FUNCTION__,				 ip6str(&uprte->rt_ripinfo.rip6_dest, 0),				 uprte->rt_ripinfo.rip6_plen,				 bgp_peerstr(bnp));		  nrte = uprte->rt_prev; /* XXX */		  remque(uprte);		  free(uprte);		  uprte = nrte;		  continue;	  } else {   /* (1998/06/30) */		  /* Copy enable route into adj-ribs-in list */		  struct rt_entry *irte;		  IFLOG(LOG_BGPINPUT)			  syslog(LOG_DEBUG,				 "<%s>: MP_REACH_NLRI %s/%d: from %s, "				 "enabled(%s)",				 __FUNCTION__,				 ip6str(&uprte->rt_ripinfo.rip6_dest, 0),				 uprte->rt_ripinfo.rip6_plen,				 bgp_peerstr(bnp),				 (uprte->rt_flags & RTF_UP) ? "installed" :				 "backup");		  MALLOC(irte, struct rt_entry);		  memcpy(irte, uprte, sizeof(struct rt_entry));		  irte->rt_aspath = aspathcpy(uprte->rt_aspath);		  if (bnp->rp_adj_ribs_in) {			  insque(irte, bnp->rp_adj_ribs_in);		  } else {			  irte->rt_next = irte->rt_prev = irte;			  bnp->rp_adj_ribs_in = irte;		  };	  }	  /* a BGP speaker advertise to its peers (other BGP speakers which it	     communicates with) in neighboring ASs only those routes that it	     itself uses [BGP4, Page2] */	  if ((bnp->rp_mode  & BGPO_IGP && uprte->rt_flags & RTF_UP &&	       ((uprte->rt_flags & RTF_IGP_EGP_SYNC) ||		(bnp->rp_mode & BGPO_NOSYNC)))	      ||	      (!(bnp->rp_mode  & BGPO_IGP) && uprte->rt_flags & RTF_UP))		  continue;	/* to next RTE */	  else {		  nrte = uprte->rt_prev; /* XXX */		  remque(uprte);		  free(uprte);		  uprte = nrte;	  }  }  /*   * withdraw route   */  for (wdrte = wdrtehead.rt_next; wdrte != &wdrtehead;       wdrte = wdrte->rt_next) {	  struct rt_entry *drte;	  if ((drte = find_rte(wdrte, bnp->rp_adj_ribs_in))) {		  if (drte->rt_flags & RTF_UP) {			  struct rt_entry rte;			  IFLOG(LOG_BGPINPUT)			    syslog(LOG_NOTICE,				   "<%s>: MP_UNREACH_NLRI %s/%d: from %s "				   "(deleted)", __FUNCTION__,				   ip6str(&wdrte->rt_ripinfo.rip6_dest, 0),				   wdrte->rt_ripinfo.rip6_plen,				   bgp_peerstr(bnp));			  bgp_disable_rte(drte);			  /* (also copy "back-pointer" ASpath pointer) */			  memcpy(&rte, wdrte, sizeof(struct rt_entry));			  rte.rt_next   = &rte;			  rte.rt_prev   = &rte;			  propagate(&rte);			  if (!bgp_rpcb_isvalid(bnp)) {				  syslog(LOG_NOTICE,					 "<%s>: rpcb %p was invalidated during "					 "a propagation",					 __FUNCTION__, bnp);				  goto done;			  }			  /* remove and free from the imported list */			  bnp->rp_adj_ribs_in 				  = rte_remove(drte, bnp->rp_adj_ribs_in);			  /* try to recovery from backup routes */			  bgp_recover_rte(&rte);			  if (!bgp_rpcb_isvalid(bnp)) {				  syslog(LOG_NOTICE,					 "<%s>: rpcb %p was invalidated during "					 "a route-recovery",					 __FUNCTION__, bnp);				  goto done;			  }		  }		  else {			  /*			   * when a backup route is withdrawn,			   * no update msg is advertized. just delete the entry.			   */#ifdef DEBUG_BGP			  syslog(LOG_NOTICE,				 "<%s>: MP_UNREACH_NLRI %s/%d: from %s (~UP)",

⌨️ 快捷键说明

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