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

📄 iv_exec.cc

📁 xorp源码hg
💻 CC
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// vim:set sts=4 ts=8:// Copyright (c) 2001-2007 International Computer Science Institute//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the "Software")// to deal in the Software without restriction, subject to the conditions// listed in the XORP LICENSE file. These conditions include: you must// preserve this copyright notice, and you cannot mention the copyright// holders in advertising related to the Software without their permission.// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This// notice is a summary of the XORP LICENSE file; the license in that file is// legally binding.#ident "$XORP: xorp/policy/backend/iv_exec.cc,v 1.13 2007/02/16 22:46:58 pavlin Exp $"#include "libxorp/xorp.h"#include "policy/common/policy_utils.hh"#include "policy/common/elem_null.hh"#include "policy/common/element.hh"#include "iv_exec.hh"IvExec::IvExec() : 	       _policies(NULL), _policy_count(0), _sman(NULL), _varrw(NULL),	       _finished(false), _fa(DEFAULT), _trash(NULL), _trashc(0),	       _trashs(2000), _os(NULL) {    unsigned ss = 128;    _trash = new Element*[_trashs];    _stack = new const Element*[ss];    _stackptr = &_stack[0];    _stackptr--;    _stackend = &_stack[ss];}IvExec::~IvExec(){    if (_policies)	delete _policies;        clear_trash();    delete _trash;    delete _stack;}IvExec::FlowAction IvExec::run(VarRW* varrw, ostream* os){    _varrw = varrw;    _os = os;    XLOG_ASSERT(_policies);    XLOG_ASSERT(_sman);    XLOG_ASSERT(_varrw);    if (!_varrw->trace_allowed())	_os = NULL;    FlowAction ret = DEFAULT;    // execute all policies    for(unsigned i = 0; i < _policy_count; ++i) {	FlowAction fa = runPolicy(*_policies[i]);	// if a policy rejected/accepted a route then terminate.	if(fa != DEFAULT) {	    ret = fa;	    break;	}    }        if(_os)	*_os << "Outcome of whole filter: " << fa2str(ret) << endl;    // important because varrw may hold pointers to trash elements    _varrw->sync();    clear_trash();        return ret;}IvExec::FlowAction IvExec::runPolicy(PolicyInstr& pi){    TermInstr** terms = pi.terms();    int termc = pi.termc();       FlowAction outcome = DEFAULT;    if(_os)	*_os << "Running policy: " << pi.name() << endl;    // run all terms    for(int i = 0; i < termc ; ++i) {	FlowAction fa = runTerm(*terms[i]);	// if term accepted/rejected route, then terminate.	if(fa != DEFAULT) {	    outcome = fa;	    break;	}        }    if(_os)	*_os << "Outcome of policy: " << fa2str(outcome) << endl;    return outcome;}IvExec::FlowAction IvExec::runTerm(TermInstr& ti){    // we just started    _finished = false;    _fa = DEFAULT;    // clear stack    _stackptr = &_stack[0];    _stackptr--;    int instrc = ti.instrc();    Instruction** instr = ti.instructions();    if(_os)	*_os << "Running term: " << ti.name() << endl;    // run all instructions    for(int i = 0; i < instrc; ++i) {	(instr[i])->accept(*this);	// a flow action occured [accept/reject/default -- exit]	if(_finished)	    break;    }    if(_os)	*_os << "Outcome of term: " << fa2str(_fa) << endl;    return _fa;}void IvExec::visit(Push& p){    const Element& e = p.elem();    // node owns element [no need to trash]    _stackptr++;    XLOG_ASSERT(_stackptr < _stackend);    *_stackptr = &e;        if(_os)	*_os << "PUSH " << e.type() << " " << e.str() << endl;}void IvExec::visit(PushSet& ps){    string name = ps.setid();    const Element& s = _sman->getSet(name);    // set manager owns set [no need to trash]    _stackptr++;    XLOG_ASSERT(_stackptr < _stackend);    *_stackptr = &s;    if(_os)	*_os << "PUSH_SET " << s.type() << " " << name	     << ": " << s.str() << endl;}void IvExec::visit(OnFalseExit& /* x */){    if (_stackptr < _stack)	xorp_throw(RuntimeError, "Got empty stack on ON_FALSE_EXIT");    // we expect a bool at the top.    const ElemBool* t = dynamic_cast<const ElemBool*>(*_stackptr);    if(!t) {	// but maybe it is a ElemNull... in which case its a NOP	const Element* e = *_stackptr;	if(e->hash() == ElemNull::_hash) {	    if(_os)		*_os << "GOT NULL ON TOP OF STACK, GOING TO NEXT TERM" << endl;	    _finished = true;	    return;        }	// if it is anything else, its an error        else {	   xorp_throw(RuntimeError, "Expected bool on top of stack instead: ");	}	        }    // we do not pop the element!!!    // The reason is, that maybe we want to stick ONFALSE_EXIT's here and there    // for optimizations to peek on the stack. Consider a giant AND, we may    // stick an ON_FALSEEXIT after earch clause of the and. In that case we do    // not wish to pop the element from the stack, as if it is true, we want to    // continue computing the AND.    // it is false, so lets go to next term    if(!t->val())	_finished = true;    if(_os)	*_os << "ONFALSE_EXIT: " << t->str() << endl;}void IvExec::visit(Load& l){    const Element& x = _varrw->read_trace(l.var());    if(_os)	*_os << "LOAD " << l.var() << ": " << x.str() << endl;    // varrw owns element [do not trash]    _stackptr++;    XLOG_ASSERT(_stackptr < _stackend);    *_stackptr = &x;}void IvExec::visit(Store& s){    if (_stackptr < _stack)	xorp_throw(RuntimeError, "Stack empty on assign of " + s.var());    const Element* arg = *_stackptr;    _stackptr--;    XLOG_ASSERT( _stackptr >= (_stack-1));    if(arg->hash() == ElemNull::_hash) {	if(_os)	    *_os << "STORE NULL [treated as NOP]" << endl;	return;    }    // we still own the element.    // if it had to be trashed, it would have been trashed on creation, so do    // NOT trash now. And yes, it likely is an element we do not have to    // trash anyway.    _varrw->write_trace(s.var(),*arg);    if(_os)	*_os << "STORE " << s.var() << ": " << arg->str() << endl;}void IvExec::visit(Accept& /* a */){    // ok we like the route, so exit all execution    _finished = true;    _fa = ACCEPT;    if(_os)	*_os << "ACCEPT" << endl;}    void IvExec::visit(Reject& /* r */){    // we don't like it, get out of here.    _finished = true;    _fa = REJ;    if(_os)	*_os << "REJECT" << endl;}voidIvExec::visit(NaryInstr& nary){    unsigned arity = nary.op().arity();    XLOG_ASSERT(_stackptr-arity+1 >= _stack);    // execute the operation    Element* r = _disp.run(nary.op(), arity, _stackptr-arity+1);    if (arity)	_stackptr -= arity -1;    else	_stackptr++;    // trash the result for deletion on completion    _trash[_trashc] = r;    _trashc++;    XLOG_ASSERT(_trashc < _trashs);    // store result on stack    XLOG_ASSERT(_stackptr < _stackend && _stackptr >= _stack);    *_stackptr = r;    // output trace    if(_os)	*_os << nary.op().str() << endl;}voidIvExec::clear_trash(){    for (unsigned i = 0; i< _trashc; i++)	delete _trash[i];    _trashc = 0;}stringIvExec::fa2str(const FlowAction& fa){    switch(fa) {	case ACCEPT:	    return "Accept";		case REJ:	    return "Reject";		case DEFAULT:	    return "Default action";    }    return "Unknown";}voidIvExec::set_policies(vector<PolicyInstr*>* policies){    if (_policies) {	delete _policies;	_policies = NULL;    }    // resetting...    if (!policies) {	_policy_count = 0;	return;    }    _policy_count = policies->size();    _policies = new PolicyInstr*[_policy_count];    vector<PolicyInstr*>::iterator iter;    unsigned i = 0;    for (iter = policies->begin(); iter != policies->end(); ++iter) {	_policies[i] = *iter;	i++;    }}voidIvExec::set_set_manager(SetManager* sman){    _sman = sman;}

⌨️ 快捷键说明

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