Пример #1
0
s32 bgp_nlri_parse_6pe (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
{
  u_char *pnt;
  u_char *lim;
  struct prefix p;
  int psize;
  int prefixlen;
  u_int32_t label;
  u_char *tagpnt;

  /* Check peer status. */
  if (peer->status != Established)
    return 0;

  pnt = packet->nlri;
  lim = pnt + packet->length;

  for (; pnt < lim; pnt += psize)
    {
      /* Clear prefix structure. */
      memset (&p, 0, sizeof (struct prefix));

      /* Fetch prefix length. */
      prefixlen = *pnt++;
      p.family = AF_INET6;
      psize = PSIZE (prefixlen);

      if (prefixlen < 24)
    {
      zlog_err ("prefix length is less than 88: %d", prefixlen);
      return -1;
    }

      label = decode_label (pnt);

      /* Copyr label to prefix. */
      tagpnt = pnt;

      p.prefixlen = prefixlen - 24;
      memcpy (&p.u.prefix, pnt + 3, psize - 3);

      if (pnt + psize > lim)
    return -1;

      if (attr)
    bgp_update (peer, &p, attr, AFI_IP6, SAFI_UNICAST,
            ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, tagpnt, 0);
      else
    bgp_withdraw (peer, &p, attr, AFI_IP6, SAFI_UNICAST,
              ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, tagpnt);
    }

  /* Packet length consistency check. */
  if (pnt != lim)
    return -1;

  return 0;
}
Пример #2
0
/* BGP massage header */
void
bgp_msg(struct pktinfo *pktinfo)
{
    int x;
    struct pktinfo n_hdr;
    const u_char *pkt = pktinfo->pkt;
    bpf_u_int32 len = pktinfo->len;
    struct bgp_hdr *bgp_hdr = (struct bgp_hdr *)pkt;
    u_int16_t bgp_len = htons(bgp_hdr->length);

    n_hdr.len = len;
    n_hdr.pkt = pkt;


    if (vflag) {
        (void)printf("BGP message marker  ");
        for (x = 0;x < 16; x++)
            (void)printf("%x",bgp_hdr->marker[x]);
        (void)printf("\n");
        (void)printf("            length %d bytes\n", bgp_len);
        if (bgp_hdr->type > 0 && bgp_hdr->type < 5)
            (void)printf("            type   %d \"%s\"\n", 
		bgp_hdr->type, bgp_types[bgp_hdr->type]);
        else
            (void)printf("            type   %d \"Invalid type\"\n", bgp_hdr->type);
    }

    switch(bgp_hdr->type) {
        case BGP_OPEN:
            bgp_open(&n_hdr, bgp_len);
            break;
        case BGP_UPDATE:
            bgp_update(&n_hdr, bgp_len);
            break;
        case BGP_NOTIFICATION:
            bgp_notify(&n_hdr, bgp_len);
            break;
        case BGP_KEEPALIVE:
            bgp_keepalive(&n_hdr, bgp_len);
            break;
        default:
            (void)printf("\"ERROR BGP Invalid Type: %d\"\n",bgp_hdr->type);
            (void)printf("\n");
            break;
    }
} /* end of bgp_msg */
Пример #3
0
int
bgp_nlri_parse_encap(
    struct peer		*peer,
    struct attr		*attr, 		/* Need even for withdraw */
    struct bgp_nlri	*packet)
{
  u_char *pnt;
  u_char *lim;
  afi_t afi = packet->afi;
  struct prefix p;
  int psize = 0;
  int prefixlen;
  struct rd_as rd_as;
  struct rd_ip rd_ip;
  struct prefix_rd prd;
  struct ecommunity *pEcom = NULL;
  u_int16_t rdtype = 0xffff;
  char buf[BUFSIZ];

  /* Check peer status. */
  if (peer->status != Established)
    return 0;
  
  /* Make prefix_rd */
  if (attr && attr->extra && attr->extra->ecommunity)
      pEcom = attr->extra->ecommunity;

  ecom2prd(pEcom, &prd);
  memset(&rd_as, 0, sizeof(rd_as));
  memset(&rd_ip, 0, sizeof(rd_ip));

  if (pEcom) {

      rdtype = (prd.val[0] << 8) | prd.val[1];

      /* Decode RD value. */
      if (rdtype == RD_TYPE_AS)
	decode_rd_as (prd.val + 2, &rd_as);
      else if (rdtype == RD_TYPE_IP)
	decode_rd_ip (prd.val + 2, &rd_ip);
      else if (rdtype == RD_TYPE_AS4)
	decode_rd_as4 (prd.val + 2, &rd_as);
      else
	{
	  zlog_err ("Invalid RD type %d", rdtype);
	}

  }

  /*
   * NB: this code was based on the MPLS VPN code, which supported RDs.
   * For the moment we are retaining the underlying RIB structure that
   * keeps a per-RD radix tree, but since the RDs are not carried over
   * the wire, we set the RD internally to 0.
   */
  prd.family = AF_UNSPEC;
  prd.prefixlen = 64;
  memset(prd.val, 0, sizeof(prd.val));

  pnt = packet->nlri;
  lim = pnt + packet->length;

  for (; pnt < lim; pnt += psize)
    {
      /* Clear prefix structure. */
      memset (&p, 0, sizeof (struct prefix));

      /* Fetch prefix length. */
      prefixlen = *pnt++;
      p.family = afi2family(afi);
      if (p.family == 0) {
	/* bad afi, shouldn't happen */
	zlog_warn("%s: bad afi %d, dropping incoming route", __func__, afi);
	continue;
      }
      psize = PSIZE (prefixlen);

      p.prefixlen = prefixlen;
      memcpy (&p.u.prefix, pnt, psize);

      if (pnt + psize > lim)
	return -1;


      if (rdtype == RD_TYPE_AS)
	zlog_info ("rd-as %u:%u prefix %s/%d", rd_as.as, rd_as.val,
		   inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
		   p.prefixlen);
      else if (rdtype == RD_TYPE_IP)
	zlog_info ("rd-ip %s:%u prefix %s/%d", inet_ntoa (rd_ip.ip),
		   rd_ip.val,
		   inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
		   p.prefixlen);
      else if (rdtype == RD_TYPE_AS4)
	zlog_info ("rd-as4 %u:%u prefix %s/%d", rd_as.as, rd_as.val,
		   inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
		   p.prefixlen);
      else
	zlog_info ("rd unknown, default to 0:0 prefix %s/%d",
	    inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
	    p.prefixlen);

      if (attr) {
	bgp_update (peer, &p, attr, afi, SAFI_ENCAP,
		    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
      } else {
	bgp_withdraw (peer, &p, attr, afi, SAFI_ENCAP,
		      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL);
      }
    }

  /* Packet length consistency check. */
  if (pnt != lim)
    return -1;

  return 0;
}