📄 bgp_output.c
字号:
} /* 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 + -