예제 #1
0
/* Fill in capability open option to the packet. */
void
bgp_open_capability (struct stream *s, struct peer *peer)
{
    u_char len;
    unsigned long cp, capp, rcapp;
    afi_t afi;
    safi_t safi;
    as_t local_as;
    u_int32_t restart_time;

    /* Remember current pointer for Opt Parm Len. */
    cp = stream_get_endp (s);

    /* Opt Parm Len. */
    stream_putc (s, 0);

    /* Do not send capability. */
    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
            || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
        return;

    /* IPv4 unicast. */
    if (peer->afc[AFI_IP][SAFI_UNICAST])
    {
        peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP);
        stream_putc (s, 0);
        stream_putc (s, SAFI_UNICAST);
    }
    /* IPv4 multicast. */
    if (peer->afc[AFI_IP][SAFI_MULTICAST])
    {
        peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP);
        stream_putc (s, 0);
        stream_putc (s, SAFI_MULTICAST);
    }
    /* IPv4 VPN */
    if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
    {
        peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP);
        stream_putc (s, 0);
        stream_putc (s, SAFI_MPLS_LABELED_VPN);
    }
    /* ENCAP */
    if (peer->afc[AFI_IP][SAFI_ENCAP])
    {
        peer->afc_adv[AFI_IP][SAFI_ENCAP] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP);
        stream_putc (s, 0);
        stream_putc (s, SAFI_ENCAP);
    }
    /* IPv6 unicast. */
    if (peer->afc[AFI_IP6][SAFI_UNICAST])
    {
        peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP6);
        stream_putc (s, 0);
        stream_putc (s, SAFI_UNICAST);
    }
    /* IPv6 multicast. */
    if (peer->afc[AFI_IP6][SAFI_MULTICAST])
    {
        peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP6);
        stream_putc (s, 0);
        stream_putc (s, SAFI_MULTICAST);
    }
    /* IPv6 VPN. */
    if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
    {
        peer->afc_adv[AFI_IP6][SAFI_MPLS_VPN] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP6);
        stream_putc (s, 0);
        stream_putc (s, SAFI_MPLS_LABELED_VPN);
    }
    /* IPv6 ENCAP. */
    if (peer->afc[AFI_IP6][SAFI_ENCAP])
    {
        peer->afc_adv[AFI_IP6][SAFI_ENCAP] = 1;
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_MP);
        stream_putc (s, CAPABILITY_CODE_MP_LEN);
        stream_putw (s, AFI_IP6);
        stream_putc (s, 0);
        stream_putc (s, SAFI_ENCAP);
    }

    /* Route refresh. */
    SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
    stream_putc (s, BGP_OPEN_OPT_CAP);
    stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
    stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
    stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
    stream_putc (s, BGP_OPEN_OPT_CAP);
    stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
    stream_putc (s, CAPABILITY_CODE_REFRESH);
    stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);

    /* AS4 */
    SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
    stream_putc (s, BGP_OPEN_OPT_CAP);
    stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
    stream_putc (s, CAPABILITY_CODE_AS4);
    stream_putc (s, CAPABILITY_CODE_AS4_LEN);
    if ( peer->change_local_as )
        local_as = peer->change_local_as;
    else
        local_as = peer->local_as;
    stream_putl (s, local_as );

    /* ORF capability. */
    for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
        for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
            if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
                    || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
            {
                bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
                bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
            }

    /* Dynamic capability. */
    if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
    {
        SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
        stream_putc (s, BGP_OPEN_OPT_CAP);
        stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
        stream_putc (s, CAPABILITY_CODE_DYNAMIC);
        stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
    }

    /* Sending base graceful-restart capability irrespective of the config */
    SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
    stream_putc (s, BGP_OPEN_OPT_CAP);
    capp = stream_get_endp (s);           /* Set Capability Len Pointer */
    stream_putc (s, 0);                   /* Capability Length */
    stream_putc (s, CAPABILITY_CODE_RESTART);
    rcapp = stream_get_endp (s);          /* Set Restart Capability Len Pointer */
    stream_putc (s, 0);
    restart_time = peer->bgp->restart_time;
    if (peer->bgp->t_startup)
    {
        SET_FLAG (restart_time, RESTART_R_BIT);
        SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_ADV);
    }
    stream_putw (s, restart_time);

    /* Send address-family specific graceful-restart capability only when GR config
       is present */
    if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
    {
        for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
            for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
                if (peer->afc[afi][safi])
                {
                    stream_putw (s, afi);
                    stream_putc (s, safi);
                    stream_putc (s, 0); //Forwarding is not retained as of now.
                }
    }

    /* Total Graceful restart capability Len. */
    len = stream_get_endp (s) - rcapp - 1;
    stream_putc_at (s, rcapp, len);

    /* Total Capability Len. */
    len = stream_get_endp (s) - capp - 1;
    stream_putc_at (s, capp, len);

    /* Total Opt Parm Len. */
    len = stream_get_endp (s) - cp - 1;
    stream_putc_at (s, cp, len);
}
예제 #2
0
/* Fill in capability open option to the packet. */
void
bgp_open_capability (struct stream *s, struct peer *peer)
{
  u_char len;
  unsigned long cp;
  afi_t afi;
  safi_t safi;
  as_t local_as;

  /* Remember current pointer for Opt Parm Len. */
  cp = stream_get_endp (s);

  /* Opt Parm Len. */
  stream_putc (s, 0);

  /* Do not send capability. */
  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN) 
      || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
    return;

  /* IPv4 unicast. */
  if (peer->afc[AFI_IP][SAFI_UNICAST])
    {
      peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP);
      stream_putc (s, 0);
      stream_putc (s, SAFI_UNICAST);
    }
  /* IPv4 multicast. */
  if (peer->afc[AFI_IP][SAFI_MULTICAST])
    {
      peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP);
      stream_putc (s, 0);
      stream_putc (s, SAFI_MULTICAST);
    }
  /* IPv4 VPN */
  if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
    {
      peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP);
      stream_putc (s, 0);
      stream_putc (s, SAFI_MPLS_LABELED_VPN);
    }
#ifdef HAVE_IPV6
  /* IPv6 unicast. */
  if (peer->afc[AFI_IP6][SAFI_UNICAST])
    {
      peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP6);
      stream_putc (s, 0);
      stream_putc (s, SAFI_UNICAST);
    }
  /* IPv6 multicast. */
  if (peer->afc[AFI_IP6][SAFI_MULTICAST])
    {
      peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP6);
      stream_putc (s, 0);
      stream_putc (s, SAFI_MULTICAST);
    }
#endif /* HAVE_IPV6 */

  /* Route refresh. */
  SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
  stream_putc (s, BGP_OPEN_OPT_CAP);
  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
  stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
  stream_putc (s, BGP_OPEN_OPT_CAP);
  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
  stream_putc (s, CAPABILITY_CODE_REFRESH);
  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);

  /* AS4 */
  SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
  stream_putc (s, BGP_OPEN_OPT_CAP);
  stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
  stream_putc (s, CAPABILITY_CODE_AS4);
  stream_putc (s, CAPABILITY_CODE_AS4_LEN);
  if ( peer->change_local_as )
    local_as = peer->change_local_as;
  else
    local_as = peer->local_as;
  stream_putl (s, local_as );

  /* ORF capability. */
  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
	  || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
	{
	  bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
	  bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
	}

  /* Dynamic capability. */
  if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
    {
      SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_DYNAMIC);
      stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
    }

  /* Graceful restart capability */
  if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
    {
      SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_RESTART);
      stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
      stream_putw (s, peer->bgp->restart_time);
     }

  /* Total Opt Parm Len. */
  len = stream_get_endp (s) - cp - 1;
  stream_putc_at (s, cp, len);
}
예제 #3
0
/* Fill in capability open option to the packet. */
void
bgp_open_capability (struct stream *s, struct peer *peer)
{
  u_char len;
  unsigned long cp;
  afi_t afi;
  safi_t safi;

  /* Remember current pointer for Opt Parm Len. */
  cp = stream_get_putp (s);

  /* Opt Parm Len. */
  stream_putc (s, 0);

  /* Do not send capability. */
  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN) 
      || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
    return;

  /* When the peer is IPv4 unicast only, do not send capability. */
  if (! peer->afc[AFI_IP][SAFI_MULTICAST] 
      && ! peer->afc[AFI_IP][SAFI_MPLS_VPN]
      && ! peer->afc[AFI_IP6][SAFI_UNICAST] 
      && ! peer->afc[AFI_IP6][SAFI_MULTICAST]
      && CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP)
      && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
		       PEER_FLAG_ORF_PREFIX_SM)
      && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
		       PEER_FLAG_ORF_PREFIX_RM)
      && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
		       PEER_FLAG_ORF_PREFIX_SM)
      && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
		       PEER_FLAG_ORF_PREFIX_RM)
      && ! CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
    return;

  /* IPv4 unicast. */
  if (peer->afc[AFI_IP][SAFI_UNICAST])
    {
      peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP);
      stream_putc (s, 0);
      stream_putc (s, SAFI_UNICAST);
    }
  /* IPv4 multicast. */
  if (peer->afc[AFI_IP][SAFI_MULTICAST])
    {
      peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP);
      stream_putc (s, 0);
      stream_putc (s, SAFI_MULTICAST);
    }
  /* IPv4 VPN */
  if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
    {
      peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP);
      stream_putc (s, 0);
      stream_putc (s, BGP_SAFI_VPNV4);
    }
#ifdef HAVE_IPV6
  /* IPv6 unicast. */
  if (peer->afc[AFI_IP6][SAFI_UNICAST])
    {
      peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP6);
      stream_putc (s, 0);
      stream_putc (s, SAFI_UNICAST);
    }
  /* IPv6 multicast. */
  if (peer->afc[AFI_IP6][SAFI_MULTICAST])
    {
      peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_MP);
      stream_putc (s, CAPABILITY_CODE_MP_LEN);
      stream_putw (s, AFI_IP6);
      stream_putc (s, 0);
      stream_putc (s, SAFI_MULTICAST);
    }
#endif /* HAVE_IPV6 */

  /* Route refresh. */
  if (! CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP))
    {
      SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
      stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_REFRESH);
      stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
    }

  /* ORF capability. */
  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
	  || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
	{
	  bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
	  bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
	}

  /* Dynamic capability. */
  if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
    {
      SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
      stream_putc (s, BGP_OPEN_OPT_CAP);
      stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
      stream_putc (s, CAPABILITY_CODE_DYNAMIC);
      stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
    }

  /* Total Opt Parm Len. */
  len = stream_get_putp (s) - cp - 1;
  stream_putc_at (s, cp, len);
}