xorp

element.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2011 XORP, Inc and Others
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License, Version 2, June
00008 // 1991 as published by the Free Software Foundation. Redistribution
00009 // and/or modification of this program under the terms of any other
00010 // version of the GNU General Public License is not permitted.
00011 // 
00012 // This program is distributed in the hope that it will be useful, but
00013 // WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00015 // see the GNU General Public License, Version 2, a copy of which can be
00016 // found in the XORP LICENSE.gpl file.
00017 // 
00018 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00019 // http://xorp.net
00020 
00021 // $XORP: xorp/policy/common/element.hh,v 1.17 2008/10/02 21:58:06 bms Exp $
00022 
00023 #ifndef __POLICY_COMMON_ELEMENT_HH__
00024 #define __POLICY_COMMON_ELEMENT_HH__
00025 
00026 
00027 
00028 #include "libxorp/ipv4.hh"
00029 #include "libxorp/ipv6.hh"
00030 #include "libxorp/ipv4net.hh"
00031 #include "libxorp/ipv6net.hh"
00032 #include "element_base.hh"
00033 #include "policy_exception.hh"
00034 #include "policy_utils.hh"
00035 #include "policy/policy_module.h"
00036 #include "operator_base.hh"
00037 
00038 enum {
00039     HASH_ELEM_INT32 = 1,
00040     HASH_ELEM_U32,
00041     HASH_ELEM_COM32,
00042     HASH_ELEM_STR,
00043     HASH_ELEM_BOOL,     // 5
00044     HASH_ELEM_IPV4,
00045     HASH_ELEM_IPV6,
00046     HASH_ELEM_IPV4RANGE,
00047     HASH_ELEM_IPV6RANGE,
00048     HASH_ELEM_IPV4NET,      // 10
00049     HASH_ELEM_IPV6NET,
00050     HASH_ELEM_U32RANGE,
00051     HASH_ELEM_SET_U32,
00052     HASH_ELEM_SET_COM32,
00053     HASH_ELEM_SET_IPV4NET,  // 15
00054     HASH_ELEM_SET_IPV6NET,
00055     HASH_ELEM_SET_STR,
00056     HASH_ELEM_NULL,
00057     HASH_ELEM_FILTER,
00058     HASH_ELEM_ASPATH,       // 20
00059     HASH_ELEM_IPV4NEXTHOP,
00060     HASH_ELEM_IPV6NEXTHOP,
00061 
00062     HASH_ELEM_MAX = 32 // must be last
00063 };
00064 
00068 class ElemInt32 : public Element {
00069 public:
00073     static const char* id;
00074     static Hash _hash;
00075 
00076     ElemInt32() : Element(_hash) {}
00077 
00088     ElemInt32(const char* c_str) : Element(_hash)
00089     {
00090     if (c_str)
00091         _val = strtol(c_str,NULL,10);
00092     else
00093         _val = 0;
00094     }
00095 
00096     ElemInt32(const int32_t val) : Element(_hash), _val(val) {}
00097 
00101     string str() const {
00102     return policy_utils::to_str(_val);
00103     }
00104 
00108     int32_t val() const { return _val; }
00109 
00110     const char* type() const { return id; }
00111 
00112 private:
00113     int32_t _val;
00114 };
00115 
00119 class ElemU32 : public Element {
00120 public:
00121     static const char* id;
00122     static Hash _hash;
00123 
00124     ElemU32() : Element(_hash) {}
00125 
00126     ElemU32(const char* c_str) : Element(_hash)
00127     {
00128     if (c_str)
00129         _val = strtoul(c_str,NULL,10); 
00130     else
00131         _val = 0;
00132     }
00133 
00134     ElemU32(const uint32_t val) : Element(_hash), _val(val) {}
00135 
00136     string str() const
00137     {
00138     return policy_utils::to_str(_val);
00139     }
00140 
00141     uint32_t val() const { return _val; }
00142     const char* type() const { return id; }
00143 
00144     bool operator==(const ElemU32& rhs) const { return _val == rhs._val; }
00145     bool operator<(const ElemU32& rhs) const { return _val < rhs._val; }
00146 
00147 private:
00148     uint32_t _val;
00149 };
00150 
00158 class ElemCom32 : public Element {
00159 public:
00160     static const char* id;
00161     static Hash _hash;
00162 
00163     ElemCom32() : Element(_hash) {}
00164     ElemCom32(const char*);     // in element.cc
00165     ElemCom32(const uint32_t val) : Element(_hash), _val(val) {}
00166 
00167     string str() const;         // in element.cc
00168     uint32_t val() const { return _val; }
00169     const char* type() const { return id; }
00170 
00171     bool operator==(const ElemCom32& rhs) const { return _val == rhs._val; }
00172     bool operator<(const ElemCom32& rhs) const { return _val < rhs._val; }
00173 
00174 
00175 private:
00176     uint32_t _val;
00177 };
00178 
00182 class ElemStr : public Element {
00183 public:
00184     static const char* id;
00185     static Hash _hash;
00186 
00187     ElemStr() : Element(_hash) {}
00188 
00189     ElemStr(const char* val) : Element(_hash)
00190     {
00191     if (val)
00192         _val = val;
00193     else
00194         _val = "";
00195     }
00196 
00197     ElemStr(const string& str) : Element(_hash), _val(str) {}
00198 
00199     string str() const { return _val; }
00200     string val() const { return _val; }
00201     const char* type() const { return id; }
00202 
00203     bool operator==(const ElemStr& rhs) const { return _val == rhs._val; }
00204     bool operator<(const ElemStr& rhs) const { return _val < rhs._val; }
00205 
00206 private:
00207     string _val;
00208 };
00209 
00213 class ElemBool : public Element {
00214 public:
00215     static const char* id;
00216     static Hash _hash;
00217 
00218     ElemBool() : Element(_hash) {}
00219 
00220     ElemBool(const char* c_str) : Element(_hash)
00221     {
00222     if (c_str && (strcmp(c_str,"true") == 0) )
00223         _val = true;
00224     else
00225         _val = false;
00226     }
00227 
00228     ElemBool(const bool val) : Element(_hash), _val(val) {}
00229 
00230     string str() const
00231     {
00232     if (_val)
00233         return "true";
00234     else
00235         return "false";
00236     }       
00237 
00238     bool val() const { return _val; }
00239     const char* type() const { return id; }
00240 
00241     bool operator==(const ElemBool& rhs) const { return _val == rhs._val; }
00242 
00243 private:
00244     bool _val;
00245 };
00246 
00247 
00255 template<class T>
00256 class ElemAny : public Element {
00257 public:
00258     
00262     class ElemInitError : public PolicyException {
00263     public:
00264     ElemInitError(const char* file, size_t line, const string& init_why = "")   
00265         : PolicyException("ElemInitError", file, line, init_why) {}  
00266     };
00267 
00268 
00269     static const char* id;
00270     static Hash _hash;
00271 
00272     ElemAny() : Element(_hash), _val() {}
00273     ElemAny(const T& val) : Element(_hash), _val(val) {}
00274 
00280     ElemAny(const char* c_str) : Element(_hash), _val()
00281     {
00282     if (c_str) {
00283         try {
00284         _val = T(c_str);
00285         } catch (...) {
00286         string err = "Unable to initialize element of type ";
00287         err += id;
00288         err += " with ";
00289         err += c_str;
00290 
00291         xorp_throw(ElemInitError, err);
00292 
00293         }
00294         
00295     }
00296     // else leave it to the default value
00297     }
00298 
00305     bool operator==(const ElemAny<T>& rhs) const {
00306     return _val == rhs._val;
00307     }
00308 
00315     bool operator<(const ElemAny<T>& rhs) const {
00316     return _val < rhs._val;
00317     }
00318     
00324     string str() const { return _val.str(); }
00325 
00329     const T& val() const { return _val; }
00330     
00331     const char* type() const { return id; }
00332 
00333 private:
00334     T _val;
00335 };
00336 
00337 template<class T>
00338 class ElemRefAny : public Element {
00339 public:
00343     class ElemInitError : public PolicyException {
00344     public:
00345     ElemInitError(const char* file, size_t line, const string& init_why = "")   
00346         : PolicyException("ElemInitError", file, line, init_why) {}
00347     };
00348 
00349     
00350     static const char* id;
00351     static Hash _hash;
00352 
00353     ElemRefAny() : Element(_hash), _val(new T()), _free(true) {}
00354     ElemRefAny(const T& val) : Element(_hash), _val(&val), _free(false) {}
00355     ElemRefAny(const T& val, bool f) : Element(_hash), _val(&val), _free(f) {}
00356 
00357     ~ElemRefAny() { if (_free) delete _val; }
00358 
00364     ElemRefAny(const char* c_str) : Element(_hash), _val(NULL), _free(false)
00365     {
00366         if (c_str) {
00367             try {
00368                 _val = new T(c_str);
00369                 _free = true;
00370             } catch(...) {
00371                 string err = "Unable to initialize element of type ";
00372                 err += id;
00373                 err += " with ";
00374                 err += c_str;
00375 
00376                 xorp_throw(ElemInitError, err);
00377 
00378             }
00379 
00380         }
00381     // else leave it to the default value
00382     else {
00383         _val = new T();
00384         _free = true;
00385         }
00386     }
00387 
00394     bool operator==(const ElemRefAny<T>& rhs) const {
00395         return (*_val) == rhs.val();
00396     }
00397 
00404     bool operator<(const ElemRefAny<T>& rhs) const {
00405         return (*_val) < rhs.val();
00406     }
00407 
00413     string str() const { return _val->str(); }
00414 
00418     const T& val() const { return *_val; }
00419 
00420     const char* type() const { return id; }
00421 
00422     ElemRefAny(const ElemRefAny<T>& copy) : Element(_hash) {
00423     _val = copy._val;
00424     _free = copy._free;
00425     copy._free = false;
00426     }
00427 
00428 private:
00429     ElemRefAny& operator=(const ElemRefAny<T>&);
00430 
00431     const T* _val;
00432     mutable bool _free;
00433 };
00434 
00435 template<class A>
00436 class ElemNet : public Element {
00437 public:
00438     enum Mod {
00439     MOD_NONE,
00440     MOD_EXACT,
00441     MOD_SHORTER,
00442     MOD_ORSHORTER,
00443     MOD_LONGER,
00444     MOD_ORLONGER,
00445     MOD_NOT
00446     };
00447 
00448     static const char*  id;
00449     static Hash     _hash;
00450 
00451     ElemNet();
00452     ElemNet(const char*);
00453     ElemNet(const A&);
00454     ElemNet(const ElemNet<A>&);     // copyable
00455     ~ElemNet();
00456 
00457     string      str() const;
00458     const char*     type() const;
00459     const A&        val() const;
00460     static Mod      str_to_mod(const char* p);
00461     static string   mod_to_str(Mod mod);
00462     BinOper&        op() const;
00463 
00464     bool    operator<(const ElemNet<A>& rhs) const;
00465     bool    operator==(const ElemNet<A>& rhs) const;
00466 
00467 #ifdef XORP_USE_USTL
00468     ElemNet& operator=(const ElemNet<A>& rhs) {
00469     if (this != &rhs) {
00470         if (_net) {
00471         delete _net;
00472         }
00473         _net = new A(*rhs._net);
00474         _mod = rhs._mod;
00475         _op = rhs._op;
00476     }
00477     return *this;
00478     }
00479 #else
00480 private:
00481     ElemNet& operator=(const ElemNet<A>&);  // not assignable
00482 #endif
00483 
00484     const A*        _net;
00485     Mod         _mod;
00486     mutable BinOper*    _op;
00487 };
00488 
00489 template <class A>
00490 class ElemNextHop : public Element {
00491 public:
00492     enum Var {
00493     VAR_NONE,
00494     VAR_DISCARD,
00495     VAR_NEXT_TABLE,
00496     VAR_PEER_ADDRESS,
00497     VAR_REJECT,
00498     VAR_SELF
00499     };
00500 
00501     static const char*  id;
00502     static Hash     _hash;
00503 
00504     ElemNextHop(const char*);
00505     ElemNextHop();
00506     ElemNextHop(const A& nh);
00507 
00508     string  str() const;
00509     const char* type() const;
00510     Var     var() const;
00511     const A&    addr() const;
00512     const A&    val() const; // for relop compatibility
00513 
00514 private:
00515     Var _var;
00516     A   _addr;
00517 };
00518 
00519 // User defined types
00520 typedef ElemRefAny<IPv4>        ElemIPv4;
00521 typedef ElemAny<IPv6>           ElemIPv6;
00522 typedef ElemAny<IPv4Range>      ElemIPv4Range;
00523 typedef ElemAny<IPv6Range>      ElemIPv6Range;
00524 typedef ElemNet<IPv4Net>        ElemIPv4Net;
00525 typedef ElemNet<IPv6Net>        ElemIPv6Net;
00526 typedef ElemAny<U32Range>       ElemU32Range;
00527 typedef ElemNextHop<IPv4>       ElemIPv4NextHop;
00528 typedef ElemNextHop<IPv6>       ElemIPv6NextHop;
00529 
00530 #endif // __POLICY_COMMON_ELEMENT_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations