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

📄 bgp_output.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 3 页
字号:
      }      /* XXX: is there any case of INSTALLED but not SYNCHRONIZED? */      if ((rtp->rtp_bgp->rp_mode & BGPO_IGP) &&	  !(rtp->rtp_bgp->rp_mode & BGPO_NOSYNC) &&	  (!(rt->rt_flags & RTF_IGP_EGP_SYNC))) {	IFLOG(LOG_BGPOUTPUT)	  syslog(LOG_DEBUG,		 "BGP+ SEND\t\t\t(was skipped since not synchronized)");	      goto next_rte;	    }    }    poctets = POCTETS(rt->rt_ripinfo.rip6_plen);    if (i + 1 + poctets > BGPMAXPACKETSIZE ) {  /* 4096 octets */      syslog(LOG_NOTICE, "<%s>: Max Size of BGP message", __FUNCTION__);      rt = rt->rt_prev;      break; /* while(rt) */    }    outpkt[i++] = rt->rt_ripinfo.rip6_plen;    memcpy(&outpkt[i], rt->rt_ripinfo.rip6_dest.s6_addr, poctets);    i +=  poctets;    IFLOG(LOG_BGPOUTPUT)      syslog(LOG_DEBUG, "BGP+ SEND\t\t%s/%d",	     ip6str(&rt->rt_ripinfo.rip6_dest, 0),	     rt->rt_ripinfo.rip6_plen);	         next_rte:    if (rt->rt_next == headrte ||	!equal_aspath(rt->rt_aspath, rt->rt_next->rt_aspath))      break;    if (rt->rt_next == rt)      fatalx("BUG!");    rt = rt->rt_next;  } /* while(rt)... End of NLRI */  /******************************/  if (IamRR &&      netorigid == bnp->rp_id) {    IFLOG(LOG_BGPOUTPUT)      syslog(LOG_DEBUG, "<%s>: Don't re-send to originator.", __FUNCTION__);    return rt;  /* pointer */  }  /* Network Layer Reachability Information Length (2 Octets) */  if ((netnlrilen = htons(i - nlri_p)) == 0) {    IFLOG(LOG_BGPOUTPUT)      syslog(LOG_DEBUG, "<%s>: Nothing to be sent for %s",	     __FUNCTION__, bgp_peerstr(bnp));    return rt;           /* (1998/06/16) */  }#ifdef DRAFT_IETF_00  memcpy(&outpkt[nlri_p - 2], &netnlrilen, 2);#endif  /*  data length of MP_REACH_NLRI  */  if (i - mp_p > 0xff) {    netmpnlrilen = htons(i - mp_p);    memcpy(&outpkt[mp_p - 2], &netmpnlrilen, 2);  } else {    outpkt[mp_p - 2] =  i - mp_p;    outpkt[mp_p - 4] &= ~PA_FLAG_EXTLEN;  /* down */    memmove(&outpkt[mp_p - 1], &outpkt[mp_p], i - mp_p);    outpkt[i--] = 0;  }  /**********                          **********/   /**********   End of MP_REACH_NLRI   **********/   /**********                          **********/   /* unrecognized but transitive path attributes */  if (rtp->rtp_type == RTPROTO_BGP &&      rte->rt_aspath) {		/* XXX: paranoid? */    for (optatr = rte->rt_aspath->asp_optatr; optatr; optatr = optatr->next) {      memcpy(&outpkt[i], optatr->data, optatr->len); /* XXX: boundary check */      /* set partial bit since we don't recognize the attribute */      outpkt[i] |= PA_FLAG_PARTIAL;      i += optatr->len;    }  }  /*** Total Path Attribute Length (2 octets) ***/  nettpalen = htons(i - topa_p);  memcpy(&outpkt[topa_p - 2], &nettpalen, 2);    /* again, total msg Length (2-octet) field in the header */  bh->bh_length = htons(i);#if 0  usleep(BGP_ADV_DELAY);#endif    /****  send UPDATE message  ****/  if ((write(bnp->rp_socket, outpkt, i)) != i) {    syslog(LOG_ERR, "<%s>: write to %s failed: %s",__FUNCTION__,	   bgp_peerstr(bnp),strerror(errno));#if 0    /*     * we don't have to(even MUST NOT) call bgp_cease() here, since     * it will be called in the caller of the function, redistribute().     * (jinmei@kame.net 19981127)     */    bgp_cease(bnp);#endif     return NULL;  }  bgp_update_stat(bnp, BGPS_UPDATESENT);  BGP_LOG_SEND(BGP_UPDATE, i);  return rt;   /* the last RTE. */}/* * *   bgp_send_withdrawn() */struct rt_entry *bgp_send_withdrawn(bnp, rte, headrte)     struct rpcb     *bnp;     struct rt_entry *rte, *headrte;/* is ring, and, may have the same aspath. */{  struct bgphdr   *bh;  int              i, topa_p, mp_p, nlri_p;            /* cursor */  u_int16_t        netafi;  u_int16_t        netmpnlrilen, nettpalen;#ifdef DRAFT_IETF_00  u_int16_t        netnlrilen;#endif  struct rt_entry *rt;  extern byte       outpkt[];  extern char      *bgp_msgstr[], *bgp_statestr[];  extern char      *pa_typestr[];  IFLOG(LOG_BGPOUTPUT)    syslog(LOG_DEBUG, "<bgp_send_withdrawn>: invoked. AS=%u, ID=%s, state=%s",	   bnp->rp_as, inet_ntoa(*(struct in_addr *)&bnp->rp_id),	   bgp_statestr[bnp->rp_state]);  if (bnp->rp_state != BGPSTATE_ESTABLISHED)    fatalx("<bgp_send_withdrawn>: internal error: invalid state");  memset(outpkt, 0, BGPMAXPACKETSIZE);  rt = NULL;  bh = (struct bgphdr *)outpkt;    /*** fixed-size header ***/  /* Marker (16 octets) (to be all 1) */  memset(bh->bh_marker, 0xff, BGP_HEADER_MARKER_LEN);  bh->bh_type = BGP_UPDATE;  /* Type   (1 octet) */  i = BGP_HEADER_LEN;  /***  Update Message Format  ***/  /* Unfeasible Routes Length (2 octets)  */   i += 2;  /* IPv6 (BGP4+) doesn't use this        */  /*   Total Path Attribute Length (2 octets) (0...65535)    */  i += 2;  topa_p = i;  /* exporting routes exist ? */  if (rte == NULL) {                /* argument */    fatalx("<bgp_send_withdrawn>: BUG !");    return NULL;  }  /*   *   Path Attributes   */  /**                                                            **/  /**   MP_UNREACH_NLRI (Type Code 14)   (optional non-transitive) **/  /**                                                            **/  outpkt[i]   |= PA_FLAG_OPT;        outpkt[i++] |= PA_FLAG_EXTLEN;  /* tmp */  outpkt[i++] =  PA4_TYPE_MPUNREACHNLRI;      /* T */  BGP_LOG_ATTR;  i += 2; /*   Extended length (temporary) */ /* L */  mp_p = i;                                              /* V */  /* Address Family Identifier (2 octets)        */  netafi = htons(AFN_IP6);  memcpy(&outpkt[i],  &netafi,  2);  i += 2;  /* Subsequent Address Family Identifier (1 octet) */  outpkt[i++] = PA4_MP_UCAST;                /* implmntd for UNIcast only */#ifdef DRAFT_IETF_00  /* Unfeasible Routes Length (2 Octets) */  i += 2;#endif  nlri_p = i;  /*** Withdrawn Routes, NLRI(+)format ***/  {    rt = rte;    while(1) {      int pbytes;     /* (minimum len in octet bound) */      if (bgp_output_filter(bnp, rt))	goto next_rte;      outpkt[i++] = rt->rt_ripinfo.rip6_plen;      IFLOG(LOG_BGPOUTPUT)	syslog(LOG_DEBUG, "BGP+ SEND MP_UNREACH\t\t%s/%d to %s",	       ip6str(&rt->rt_ripinfo.rip6_dest, 0),	       rt->rt_ripinfo.rip6_plen,	       bgp_peerstr(bnp));      pbytes = POCTETS(rt->rt_ripinfo.rip6_plen);      if (i + pbytes > BGPMAXPACKETSIZE ) {	syslog(LOG_NOTICE, "<bgp_send_withdrawn>: Too Large NLRI");	i--;	break;      }      memcpy(&outpkt[i], rt->rt_ripinfo.rip6_dest.s6_addr, pbytes);      i += pbytes;    next_rte:      if (rt->rt_next == headrte ||	  !equal_aspath(rt->rt_aspath, rt->rt_next->rt_aspath))	      break;      rt = rt->rt_next;    }  }   /* End of NLRI */#ifdef DRAFT_IETF_00  /* Unfeasible Routes length (2 Octets) */  netnlrilen = htons(i - nlri_p);  memcpy(&outpkt[nlri_p - 2], &netnlrilen, 2);#endif      /* data length of MP_UNREACH_NLRI */  if (i - mp_p > 0xff) {    netmpnlrilen = htons(i - mp_p);    memcpy(&outpkt[mp_p - 2], &netmpnlrilen, 2);  } else {    outpkt[mp_p - 2] =  i - mp_p;    outpkt[mp_p - 4] &= ~PA_FLAG_EXTLEN;  /* down */    memmove(&outpkt[mp_p - 1], &outpkt[mp_p], i - mp_p);    outpkt[i--] = 0;  }  /**********                            **********/   /**********   End of MP_UnReach_NLRI   **********/   /**********                            **********/   /* Total Path Attribute Length (2 octets) */  nettpalen = htons(i - topa_p);  memcpy(&outpkt[topa_p - 2], &nettpalen, 2);    /* again, total msg Length (2-octet) field in the header */  bh->bh_length = htons(i);#if 0  usleep(BGP_ADV_DELAY);#endif  /****  send UPDATE message  ****/   if ((write(bnp->rp_socket, outpkt, i)) != i) {    syslog(LOG_ERR, "<%s>: write %s failed: %s",	   __FUNCTION__, bgp_peerstr(bnp), strerror(errno));    return NULL;  }  bgp_update_stat(bnp, BGPS_UPDATESENT);  bgp_update_stat(bnp, BGPS_WITHDRAWSENT);  BGP_LOG_SEND(BGP_UPDATE, i);  return rt;   /* the last RTE. */}voidbgp_dump(struct rpcb *bnp) {    struct rtproto     *rtp;    struct rt_entry    *rtehead, *rte;  /*  advertising  */    struct rt_entry    *last;           /*  (1998/05/29) */    extern char        *bgp_statestr[];    IFLOG(LOG_BGPOUTPUT)      syslog(LOG_DEBUG,	     "<bgp_dump>: invoked for %s (AS=%u, ID=%s, state=%s)",	     bgp_peerstr(bnp), bnp->rp_as,	     inet_ntoa(*(struct in_addr *)&bnp->rp_id),	     bgp_statestr[bnp->rp_state]);    aggr_flush();    rtp = bnp->rp_adj_ribs_out;    /* we're gonna send DUMP */    while (rtp) {      rtehead = NULL;       /* (1998/06/10) */      switch (rtp->rtp_type) {      case RTPROTO_IF:	/* In IBGP world, Split Holizon is commited. */	if (!((bnp->rp_mode & BGPO_IGP) &&	      bnp->rp_ife == rtp->rtp_if))	  if (bgp_send_update(bnp, rtp->rtp_if->ifi_rte, rtp->rtp_if->ifi_rte)	      == NULL){ /* a few */	    bgp_cease(bnp); /* (1998/05/29) */	    return;	  }	break;      case RTPROTO_BGP:      {	      struct rpcb *ebnp = find_epeer_by_rpcb(rtp->rtp_bgp);	      if (ebnp)		      rtehead = ebnp->rp_adj_ribs_in;	      rte = rtehead;	      while(rte) { /* pointer maybe shifted */		      if ((last = bgp_send_update(bnp, rte, rtehead)) == NULL) {			      /* (1998/05/29) */			      bgp_cease(bnp);			      return;		      }		      if ((rte != rtehead) && (last == rtehead))			      break;		      if ((rte = last->rt_next) == rtehead)   /* head ? */			      break;	      }	      break;      }      case RTPROTO_RIP:	rtehead = rtp->rtp_rip->rip_adj_ribs_in;  /* (first redistribute) */	rte = rtehead;	while(rte) { /* pointer maybe shifted */	  if ((last = bgp_send_update(bnp, rte, rtehead)) == NULL) { /* (1998/05/29) */	    bgp_cease(bnp);	    return;	  }	  if ((rte != rtehead) && (last == rtehead))	    break;	  if ((rte = last->rt_next) == rtehead)   /* head ? */	    break;	}	break;      default:	fatalx("<bgp_dump>: BUG !");	break;	      }      if ((rtp = rtp->rtp_next) == bnp->rp_adj_ribs_out)	break;    } /*  while(rtp) */    IFLOG(LOG_BGPOUTPUT)      syslog(LOG_DEBUG, "<bgp_dump>: done.");    return;}#undef BGP_LOG_ATTR#undef BGP_LOG_SEND

⌨️ 快捷键说明

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