1 //  $Id$
2 // Copyright (c) 2001,2002                        RIPE NCC
3 //
4 // All Rights Reserved
5 //
6 // Permission to use, copy, modify, and distribute this software and its
7 // documentation for any purpose and without fee is hereby granted,
8 // provided that the above copyright notice appear in all copies and that
9 // both that copyright notice and this permission notice appear in
10 // supporting documentation, and that the name of the author not be
11 // used in advertising or publicity pertaining to distribution of the
12 // software without specific, written prior permission.
13 //
14 // THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 // ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
16 // AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
17 // DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
18 // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 //
21 //
22 //  Copyright (c) 1994 by the University of Southern California
23 //  All rights reserved.
24 //
25 //    Permission is hereby granted, free of charge, to any person obtaining a copy
26 //    of this software and associated documentation files (the "Software"), to deal
27 //    in the Software without restriction, including without limitation the rights
28 //    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29 //    copies of the Software, and to permit persons to whom the Software is
30 //    furnished to do so, subject to the following conditions:
31 //
32 //    The above copyright notice and this permission notice shall be included in
33 //    all copies or substantial portions of the Software.
34 //
35 //    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36 //    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37 //    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38 //    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39 //    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40 //    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 //    THE SOFTWARE.
42 //
43 //  Questions concerning this software should be directed to
44 //  irrtoolset@cs.usc.edu.
45 //
46 //  Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>
47 
48 // Comments:
49 // any dynamic memory allocated by lexer or parser
50 // is claimed by the constructors here
51 // They are either used internally or deleted using delete!
52 // if a pointer points to something in the dictionary, that is not claimed
53 
54 #ifndef POLICY_HH
55 #define POLICY_HH
56 
57 #include "config.h"
58 #include <sstream>  // For class ostream
59 #include <cassert>
60 extern "C" {
61 #ifdef HAVE_MALLOC_H
62 #include <malloc.h>
63 #endif // HAVE_MALLOC_H
64 }
65 #include "List.hh"
66 #include "symbols.hh"
67 #include "prefix.hh"
68 #include "rpsl_filter.hh"
69 
70 #ifdef ENABLE_DEBUG
71 #define INDENT(indent) for (int iii = 0; iii < indent; iii++) os << " "
72 #endif // ENABLE_DEBUG
73 
74 typedef unsigned int ASt;
75 
76 class AttrRPAttr;
77 class AttrMethod;
78 
79 class Policy {
80 public:
~Policy()81    virtual ~Policy() {}
82    virtual std::ostream& print(std::ostream &out) const;
83    virtual Policy* dup() const = 0;
84 
85 #ifdef ENABLE_DEBUG
86    virtual const char *className(void) const = 0;
printClass(std::ostream & os,int indent) const87    virtual void printClass(std::ostream &os, int indent) const {
88       INDENT(indent); os << "(*** Need more work here ***)" << std::endl;
89    }
90 #endif // ENABLE_DEBUG
91 };
92 
operator <<(std::ostream & out,const Policy & p)93 inline std::ostream &operator<<(std::ostream &out, const Policy &p) {
94    return p.print(out);
95 }
96 
97 class PolicyPeering: public Policy {
98 public:
99    Filter      *peerASes;
100    Filter      *peerRtrs;
101    Filter      *localRtrs;
102    SymID        prngSet;
103 public:
PolicyPeering(Filter * asExp,Filter * rtrExp,Filter * lRtrExp)104    PolicyPeering(Filter *asExp, Filter *rtrExp, Filter *lRtrExp)
105       : peerASes(asExp), peerRtrs(rtrExp), localRtrs(lRtrExp), prngSet(NULL) {
106    }
PolicyPeering(SymID pSet)107    PolicyPeering(SymID pSet)
108       : peerASes(NULL), peerRtrs(NULL), localRtrs(NULL), prngSet(pSet) {
109    }
PolicyPeering(const PolicyPeering & pt)110    PolicyPeering(const PolicyPeering &pt) : prngSet(pt.prngSet) {
111       peerASes  = pt.peerASes ? pt.peerASes->dup() : NULL;
112       peerRtrs  = pt.peerRtrs ? pt.peerRtrs->dup() : NULL;
113       localRtrs = pt.localRtrs ? pt.localRtrs->dup() : NULL;
114    }
~PolicyPeering()115    virtual ~PolicyPeering() {
116       if (peerASes)
117 	 delete peerASes;
118       if (peerRtrs)
119 	 delete peerRtrs;
120       if (localRtrs)
121 	 delete localRtrs;
122    }
123 
124    virtual std::ostream& print(std::ostream &out) const;
dup() const125    virtual Policy *dup() const {
126       return new PolicyPeering(*this);
127    }
128 #ifdef ENABLE_DEBUG
className(void) const129    virtual const char *className(void) const {
130       return "PolicyPeering";
131    }
printClass(std::ostream & os,int indent) const132    virtual void printClass(std::ostream &os, int indent) const {
133       // For peerASSet
134       INDENT(indent);
135    }
136 #endif // ENABLE_DEBUG
137 };
138 
139 class PolicyAction: public Policy, public ListNode {
140 public:
141    const AttrRPAttr     *rp_attr;   // into rp-attribute in the dictionary
142    const AttrMethod     *rp_method; // into the method
143    ItemList             *args;      // arguments to the method
144 
145 public:
PolicyAction(const AttrRPAttr * _rp_attr,const AttrMethod * _rp_mtd,ItemList * _args)146    PolicyAction(const AttrRPAttr *_rp_attr, const AttrMethod *_rp_mtd,
147 		ItemList *_args):
148       rp_attr(_rp_attr), rp_method(_rp_mtd), args(_args) {}
PolicyAction(const PolicyAction & pt)149    PolicyAction(const PolicyAction &pt) :
150       rp_attr(pt.rp_attr), rp_method(pt.rp_method) {
151       args = new ItemList(*pt.args);
152    }
~PolicyAction()153    virtual ~PolicyAction() {
154       delete args;
155    }
156    virtual std::ostream& print(std::ostream &out) const;
dup() const157    virtual Policy *dup() const {
158       return new PolicyAction(*this);
159    }
160 #ifdef ENABLE_DEBUG
className(void) const161    virtual const char *className(void) const {
162       return "PolicyAction";
163    }
printClass(std::ostream & os,int indent) const164    virtual void printClass(std::ostream &os, int indent) const {
165       // For rp_attr
166       INDENT(indent); os << "rp_attr" << std::endl;
167       INDENT(indent); os << "  _name = \"" << "\"" << std::endl;
168       INDENT(indent); os << "  methods (RPMethod *)" << std::endl;
169       INDENT(indent); os << "    _name = \"" << "\"" << std::endl;
170       // For rp_method
171       INDENT(indent); os << "rp_method" << std::endl;
172       INDENT(indent); os << "  _name = \"" << "\"" << std::endl;
173       // For rp_args
174       INDENT(indent); os << "args (ItemList *)" << std::endl;
175       args->printClass(os, indent + 2);
176    }
177 #endif // ENABLE_DEBUG
178 };
179 
180 class PolicyActionList: public Policy, public List<PolicyAction> {
181 public:
PolicyActionList()182    PolicyActionList() {
183    }
~PolicyActionList()184    virtual ~PolicyActionList() {
185       List<PolicyAction>::clear();
186    }
187    virtual std::ostream& print(std::ostream &out) const;
dup() const188    virtual Policy *dup() const {
189       return new PolicyActionList(*this);
190    }
191 #ifdef ENABLE_DEBUG
className(void) const192    virtual const char *className(void) const {
193       return "PolicyActionList";
194    }
printClass(std::ostream & os,int indent) const195    virtual void printClass(std::ostream &os, int indent) const {
196       for (PolicyAction *node = head(); node; node = next(node))
197 	 node->printClass(os, indent);
198    }
199 #endif // ENABLE_DEBUG
200 };
201 
202 class PolicyPeeringAction: public Policy, public ListNode {
203 public:
204    PolicyPeering     *peering;
205    PolicyActionList  *action;
206 public:
PolicyPeeringAction(PolicyPeering * p,PolicyActionList * a)207    PolicyPeeringAction(PolicyPeering *p, PolicyActionList *a) :
208       peering(p), action(a) {
209    }
PolicyPeeringAction(const PolicyPeeringAction & b)210    PolicyPeeringAction(const PolicyPeeringAction &b) {
211       peering = new PolicyPeering(*b.peering);
212       action  = new PolicyActionList(*b.action);
213    }
~PolicyPeeringAction()214    virtual ~PolicyPeeringAction() {
215       delete peering;
216       delete action;
217    }
218    virtual std::ostream& print(std::ostream &out) const;
dup() const219    virtual Policy *dup() const {
220       return new PolicyPeeringAction(*this);
221    }
222 #ifdef ENABLE_DEBUG
className(void) const223    virtual const char *className(void) const {
224       return "PolicyPeeringAction";
225    }
printClass(std::ostream & os,int indent) const226    virtual void printClass(std::ostream &os, int indent) const {
227       INDENT(indent); os << "peering (PolicyPeering *)" << std::endl;
228       peering->printClass(os, indent + 2);
229       INDENT(indent); os << "action (PolicyActionList *)" << std::endl;
230       action->printClass(os, indent + 2);
231    }
232 #endif // ENABLE_DEBUG
233 };
234 
235 class PolicyFactor: public Policy, public ListNode {
236 public:
237    List<PolicyPeeringAction> *peeringActionList;
238    Filter        *filter;
239 public:
PolicyFactor(List<PolicyPeeringAction> * pAL,Filter * _filter)240    PolicyFactor(List<PolicyPeeringAction> *pAL, Filter *_filter) :
241       peeringActionList(pAL), filter(_filter) {
242    }
PolicyFactor(const PolicyFactor & pt)243    PolicyFactor(const PolicyFactor &pt) {
244       peeringActionList = new List<PolicyPeeringAction>(*pt.peeringActionList);
245       filter  = (Filter *)pt.filter->dup();
246    }
~PolicyFactor()247    virtual ~PolicyFactor() {
248       delete peeringActionList;
249       delete filter;
250    }
251    virtual std::ostream& print(std::ostream &out) const;
dup() const252    virtual Policy *dup() const {
253       return new PolicyFactor(*this);
254    }
255 #ifdef ENABLE_DEBUG
className(void) const256    virtual const char *className(void) const {
257       return "PolicyFactor";
258    }
printClass(std::ostream & os,int indent) const259    virtual void printClass(std::ostream &os, int indent) const {
260       // Action
261       INDENT(indent); os << "peeringActionList" << std::endl;
262       for (PolicyPeeringAction *pc = peeringActionList->head();
263 	   pc;
264 	   pc = peeringActionList->next(pc)) {
265 	 pc->printClass(os, indent + 2);
266       }
267       // Filter
268       INDENT(indent); os << "filter (Filter *)" << std::endl;
269       filter->printClass(os, indent + 2);
270    }
271 #endif // ENABLE_DEBUG
272 };
273 
274 class PolicyExpr: public Policy {
275 };
276 
277 class PolicyTerm: public PolicyExpr, public List<PolicyFactor> {
278 public:
279    // PolicyTerm();
280    // PolicyTerm(const PolicyTerm &b);
~PolicyTerm()281    virtual ~PolicyTerm() {
282       List<PolicyFactor>::clear();
283    }
284    virtual std::ostream& print(std::ostream &out) const;
dup() const285    virtual Policy *dup() const {
286       return new PolicyTerm(*this);
287    }
288 #ifdef ENABLE_DEBUG
className(void) const289    virtual const char *className(void) const {
290       return "PolicyTerm";
291    }
printClass(std::ostream & os,int indent) const292    virtual void printClass(std::ostream &os, int indent) const {
293       for (PolicyFactor *pf = head(); pf; pf = next(pf)) {
294 	 pf->printClass(os, indent);
295       }
296    }
297 #endif // ENABLE_DEBUG
298 };
299 
300 class PolicyRefine: public PolicyExpr {
301 public:
302    PolicyExpr *left;
303    PolicyExpr *right;
304 public:
PolicyRefine(PolicyExpr * l,PolicyExpr * r)305    PolicyRefine(PolicyExpr *l, PolicyExpr *r) : left(l), right(r) {}
PolicyRefine(const PolicyRefine & b)306    PolicyRefine(const PolicyRefine &b) {
307       left  = (PolicyExpr *) b.left->dup();
308       right = (PolicyExpr *) b.right->dup();
309    }
~PolicyRefine()310    virtual ~PolicyRefine() {
311       delete left;
312       delete right;
313    }
314    virtual std::ostream& print(std::ostream &out) const;
dup() const315    virtual Policy *dup() const {
316       return new PolicyRefine(*this);
317    }
318 #ifdef ENABLE_DEBUG
className(void) const319    virtual const char *className(void) const {
320       return "PolicyRefine";
321    }
printClass(std::ostream & os,int indent) const322    virtual void printClass(std::ostream &os, int indent) const {
323       INDENT(indent); os << "left" << std::endl;
324       left->printClass(os, indent + 2);
325       INDENT(indent); os << "right" << std::endl;
326       right->printClass(os, indent + 2);
327    }
328 #endif // ENABLE_DEBUG
329 };
330 
331 class PolicyExcept: public PolicyExpr {
332 public:
333    PolicyExpr *left;
334    PolicyExpr *right;
335 public:
PolicyExcept(PolicyExpr * l,PolicyExpr * r)336    PolicyExcept(PolicyExpr *l, PolicyExpr *r) : left(l), right(r) {}
PolicyExcept(const PolicyExcept & b)337    PolicyExcept(const PolicyExcept &b) {
338       left  = (PolicyExpr *) b.left->dup();
339       right = (PolicyExpr *) b.right->dup();
340    }
~PolicyExcept()341    virtual ~PolicyExcept() {
342       delete left;
343       delete right;
344    }
345    virtual std::ostream& print(std::ostream &out) const;
dup() const346    virtual Policy *dup() const {
347       return new PolicyExcept(*this);
348    }
349 #ifdef ENABLE_DEBUG
className(void) const350    virtual const char *className(void) const {
351       return "PolicyExcept";
352    }
printClass(std::ostream & os,int indent) const353    virtual void printClass(std::ostream &os, int indent) const {
354       INDENT(indent); os << "left" << std::endl;
355       left->printClass(os, indent + 2);
356       INDENT(indent); os << "right" << std::endl;
357       right->printClass(os, indent + 2);
358    }
359 #endif // ENABLE_DEBUG
360 };
361 
362 #endif   // POLICY_HH
363