Revision b10e01d6

b/flowspec/admin.py
10 10
        applier = PR.Applier(route_objects=queryset)
11 11
        commit, response = applier.apply(configuration=applier.delete_routes())
12 12
        if commit:
13
            rows = queryset.update(is_online=False)
13
            rows = queryset.update(is_online=False, is_active=False)
14 14
            queryset.update(response="Successfully removed route from network")
15 15
            self.message_user(request, "Successfully removed %s routes from network" % rows)
16 16
        else:
17 17
            self.message_user(request, "Could not remove routes from network")
18
    deactivate.short_description = "Remove selected routes from network"
19

  
20
    list_display = ('name', 'get_match', 'get_then', 'is_online', 'applier', 'response')
21
    fields = ('name', 'match','then','applier', 'expires')
18
    deactivate.short_description = "Deactivate selected routes from network"
19

  
20
    list_display = ('name', 'is_online', 'applier', 'get_match', 'get_then', 'response')
21
    fieldsets = [
22
        (None,               {'fields': ['name',]}),
23
        ("Match",               {'fields': ['source', 'sourceport', 'destination', 'destinationport', 'port']}),
24
        ('Advanced Match Statements', {'fields': ['dscp', 'fragmenttype', 'icmpcode', 'icmptype', 'packetlength', 'protocol', 'tcpflag'], 'classes': ['collapse']}),
25
        ("Then",               {'fields': ['then' ]}),
26
        (None,               {'fields': ['comments',]}),
27
        
28
    ]
29
#    fields = ('name', 'applier', 'expires')
22 30

  
23 31
    #def formfield_for_dbfield(self, db_field, **kwargs):
24 32
    #    if db_field.name == 'password':
25 33
    #        kwargs['widget'] = PasswordInput
26 34
    #    return db_field.formfield(**kwargs)
27 35

  
28
admin.site.register(MatchAddress)
36
#admin.site.register(MatchAddress)
29 37
admin.site.register(MatchPort)
30 38
admin.site.register(MatchDscp)
31
admin.site.register(MatchFragmentType)
32
admin.site.register(MatchIcmpCode)
33
admin.site.register(MatchIcmpType)
34
admin.site.register(MatchPacketLength)
35
admin.site.register(MatchProtocol)
36
admin.site.register(MatchTcpFlag)
39
#admin.site.register(MatchFragmentType)
40
#admin.site.register(MatchIcmpCode)
41
#admin.site.register(MatchIcmpType)
42
#admin.site.register(MatchPacketLength)
43
#admin.site.register(MatchProtocol)
44
#admin.site.register(MatchTcpFlag)
37 45
admin.site.register(ThenAction)
38
admin.site.register(ThenStatement)
39
admin.site.register(MatchStatement)
46
#admin.site.register(ThenStatement)
47
#admin.site.register(MatchStatement)
40 48
admin.site.register(Route, RouteAdmin)
41 49

  
42 50
admin.site.disable_action('delete_selected')
b/flowspec/models.py
2 2
# vim: tabstop=4:shiftwidth=4:softtabstop=4:expandtab
3 3

  
4 4
from django.db import models
5
from django.conf import settings
5 6
from django.contrib.auth.models import User
6 7
from utils import proxy as PR
7 8
from ipaddr import *
9
from datetime import *
8 10
import logging
9 11

  
10 12
FORMAT = '%(asctime)s %(levelname)s: %(message)s'
......
32 34
)
33 35

  
34 36

  
37
def days_offset(): return datetime.now() + timedelta(days = settings.EXPIRATION_DAYS_OFFSET)
35 38
    
36
class MatchAddress(models.Model):
37
    address = models.CharField(max_length=255, help_text=u"Network address. Use address/CIDR notation")
38
    def __unicode__(self):
39
        return self.address
40

  
41
    def clean(self, *args, **kwargs):
42
        from django.core.exceptions import ValidationError
43
        try:
44
            address = IPNetwork(self.address)
45
            self.address = address.exploded
46
        except Exception:
47
            raise ValidationError('Invalid network address format')
48

  
49
    class Meta:
50
        db_table = u'match_address'
51

  
52 39
class MatchPort(models.Model):
53 40
    port = models.CharField(max_length=24)
54 41
    def __unicode__(self):
......
65 52

  
66 53
   
67 54
class ThenAction(models.Model):
68
    action = models.CharField(max_length=60, choices=THEN_CHOICES)
69
    action_value = models.CharField(max_length=255, blank=True, null=True)
55
    action = models.CharField(max_length=60, choices=THEN_CHOICES, verbose_name="Action")
56
    action_value = models.CharField(max_length=255, blank=True, null=True, verbose_name="Action Value")
70 57
    def __unicode__(self):
71
        return "%s %s" %(self.action, self.action_value)
58
        return "%s: %s" %(self.action, self.action_value)
72 59
    class Meta:
73 60
        db_table = u'then_action'
74 61

  
75 62
class Route(models.Model):
76 63
    name = models.CharField(max_length=128)
77 64
    applier = models.ForeignKey(User)
78
    destination = models.CharField(max_length=32, blank=True, null=True, help_text=u"Network address. Use address/CIDR notation")
79
    destinationport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchDestinationPort")
80
    dscp = models.ManyToManyField(MatchDscp, blank=True, null=True)
81
    fragmenttype = models.CharField(max_length=20, choices=FRAGMENT_CODES, blank=True, null=True)
82
    icmpcode = models.CharField(max_length=32, blank=True, null=True)
83
    icmptype = models.CharField(max_length=32, blank=True, null=True)
84
    packetlength = models.IntegerField(blank=True, null=True)
85
    port = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchPort")
86
    protocol = models.CharField(max_length=32, blank=True, null=True)
87
    source = models.CharField(max_length=32, blank=True, null=True, help_text=u"Network address. Use address/CIDR notation")
88
    sourceport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchSourcePort")
89
    tcpflag = models.CharField(max_length=128, blank=True, null=True)
90
    then = models.ManyToManyField(ThenAction)
65
    source = models.CharField(max_length=32, blank=True, null=True, help_text=u"Network address. Use address/CIDR notation", verbose_name="Source Address")
66
    sourceport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchSourcePort", verbose_name="Source Port")
67
    destination = models.CharField(max_length=32, blank=True, null=True, help_text=u"Network address. Use address/CIDR notation", verbose_name="Destination Address")
68
    destinationport = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchDestinationPort", verbose_name="Destination Port")
69
    port = models.ManyToManyField(MatchPort, blank=True, null=True, related_name="matchPort", verbose_name="Port" )
70
    dscp = models.ManyToManyField(MatchDscp, blank=True, null=True, verbose_name="DSCP")
71
    fragmenttype = models.CharField(max_length=20, choices=FRAGMENT_CODES, blank=True, null=True, verbose_name="Fragment Type")
72
    icmpcode = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Code")
73
    icmptype = models.CharField(max_length=32, blank=True, null=True, verbose_name="ICMP Type")
74
    packetlength = models.IntegerField(blank=True, null=True, verbose_name="Packet Length")
75
    protocol = models.CharField(max_length=32, blank=True, null=True, verbose_name="Protocol")
76
    tcpflag = models.CharField(max_length=128, blank=True, null=True, verbose_name="TCP flag")
77
    then = models.ManyToManyField(ThenAction, verbose_name="Then")
91 78
    filed = models.DateTimeField(auto_now_add=True)
92 79
    last_updated = models.DateTimeField(auto_now=True)
93 80
    is_online = models.BooleanField(default=False)
94 81
    is_active = models.BooleanField(default=False)
95
    expires = models.DateTimeField()
82
    expires = models.DateField(default=days_offset)
96 83
    response = models.CharField(max_length=512, blank=True, null=True)
97
    comments = models.TextField(null=True, blank=True)
84
    comments = models.TextField(null=True, blank=True, verbose_name="Comments")
98 85

  
99 86
    
100 87
    def __unicode__(self):
101 88
        return self.name
102 89
    
103 90
    class Meta:
91
        unique_together = (("name", "is_active"),)
104 92
        db_table = u'route'
105 93
    
106 94
    def clean(self, *args, **kwargs):
107 95
        from django.core.exceptions import ValidationError
108 96
        if self.destination:
109 97
            try:
110
                address = IPNetwork(self.address)
111
                self.address = address.exploded
98
                address = IPNetwork(self.destination)
99
                self.destination = address.exploded
112 100
            except Exception:
113
                raise ValidationError('Invalid network address format')
101
                raise ValidationError('Invalid network address format at Destination Field')
114 102
        if self.source:
115 103
            try:
116
                address = IPNetwork(self.address)
117
                self.address = address.exploded
104
                address = IPNetwork(self.source)
105
                self.source = address.exploded
118 106
            except Exception:
119
                raise ValidationError('Invalid network address format')
107
                raise ValidationError('Invalid network address format at Source Field')
120 108
    
121 109
    def save(self, *args, **kwargs):
122 110
        applier = PR.Applier(route_object=self)
123 111
        commit, response = applier.apply()
124 112
        if commit:
125 113
            self.is_online = True
114
            self.is_active = True
126 115
            self.response = response
127 116
        else:
128 117
            self.is_online = False
129 118
            self.response = response
130 119
        super(Route, self).save(*args, **kwargs)
131
    
120

  
132 121
    def is_synced(self):
133 122
        
134 123
        found = False
......
144 133
                found = True
145 134
                logger.info('Found a matching route name')
146 135
                devicematch = route.match
147
                routematch = self.match
148 136
                try:
149
                    assert(routematch.matchDestination.address)
137
                    assert(self.destination)
150 138
                    assert(devicematch['destination'][0])
151
                    if routematch.matchDestination.address == devicematch['destination'][0]:
139
                    if self.destination == devicematch['destination'][0]:
152 140
                        found = found and True
153 141
                        logger.info('Found a matching destination')
154 142
                    else:
......
157 145
                except:
158 146
                    pass
159 147
                try:
160
                    assert(routematch.matchSource.address)
148
                    assert(self.source)
161 149
                    assert(devicematch['source'][0])
162
                    if routematch.matchSource.address == devicematch['source'][0]:
150
                    if self.source == devicematch['source'][0]:
163 151
                        found = found and True
164 152
                        logger.info('Found a matching source')
165 153
                    else:
......
168 156
                except:
169 157
                    pass
170 158
                try:
171
                    assert(routematch.matchfragmenttype.fragmenttype)
159
                    assert(self.fragmenttype)
172 160
                    assert(devicematch['fragment'][0])
173
                    if routematch.matchfragmenttype.fragmenttype == devicematch['fragment'][0]:
161
                    if self.fragmenttype == devicematch['fragment'][0]:
174 162
                        found = found and True
175 163
                        logger.info('Found a matching fragment type')
176 164
                    else:
......
179 167
                except:
180 168
                    pass
181 169
                try:
182
                    assert(routematch.matchicmpcode.icmp_code)
170
                    assert(self.icmpcode)
183 171
                    assert(devicematch['icmp-code'][0])
184
                    if routematch.matchicmpcode.icmp_code == devicematch['icmp-code'][0]:
172
                    if self.icmpcode == devicematch['icmp-code'][0]:
185 173
                        found = found and True
186 174
                        logger.info('Found a matching icmp code')
187 175
                    else:
......
190 178
                except:
191 179
                    pass
192 180
                try:
193
                    assert(routematch.matchicmptype.icmp_type)
181
                    assert(self.icmptype)
194 182
                    assert(devicematch['icmp-type'][0])
195
                    if routematch.matchicmpcode.icmp_type == devicematch['icmp-type'][0]:
183
                    if self.icmptype == devicematch['icmp-type'][0]:
196 184
                        found = found and True
197 185
                        logger.info('Found a matching icmp type')
198 186
                    else:
......
201 189
                except:
202 190
                    pass
203 191
                try:
204
                    assert(routematch.matchprotocol.protocol)
192
                    assert(self.protocol)
205 193
                    assert(devicematch['protocol'][0])
206
                    if routematch.matchprotocol.protocol == devicematch['protocol'][0]:
194
                    if self.protocol == devicematch['protocol'][0]:
207 195
                        found = found and True
208 196
                        logger.info('Found a matching protocol')
209 197
                    else:
......
217 205
        
218 206
        return found
219 207

  
220
    
221 208
    def get_then(self):
222 209
        ret = ''
223
        then_statements = self.then.thenaction.all()
210
        then_statements = self.then.all()
224 211
        for statement in then_statements:
225 212
            if statement.action_value:
226 213
                ret = "%s %s:<strong>%s</strong><br/>" %(ret, statement.action, statement.action_value)
......
230 217
    
231 218
    get_then.short_description = 'Then statement'
232 219
    get_then.allow_tags = True
233

  
220
#
234 221
    def get_match(self):
235 222
        ret = ''
236
        match = self.match
237
        if match.matchDestination:
238
            ret = ret = '%s Destination Address:<strong>%s</strong><br/>' %(ret, match.matchDestination)
239
        if match.matchfragmenttype:
240
            ret = ret = "%s Fragment Type:<strong>%s</strong><br/>" %(ret, match.matchfragmenttype)
241
        if match.matchicmpcode:
242
            ret = ret = "%s ICMP code:<strong>%s</strong><br/>" %(ret, match.matchicmpcode)
243
        if match.matchicmptype:
244
            ret = ret = "%s ICMP Type:<strong>%s</strong><br/>" %(ret, match.matchicmptype)
245
        if match.matchpacketlength:
246
            ret = ret = "%s Packet Length:<strong>%s</strong><br/>" %(ret, match.matchpacketlength)
247
        if match.matchprotocol:
248
            ret = ret = "%s Protocol:<strong>%s</strong><br/>" %(ret, match.matchprotocol)
249
        if match.matchSource:
250
            ret = ret = "%s Source Address:<strong>%s</strong><br/>" %(ret, match.matchSource)
251
        if match.matchTcpFlag:
252
            ret = ret = "%s TCP flag:<strong>%s</strong><br/>" %(ret, match.matchTcpFlag)
253
        if match.matchport:
254
            for port in match.matchport.all():
223
        if self.destination:
224
            ret = ret = '%s Destination Address:<strong>%s</strong><br/>' %(ret, self.destination)
225
        if self.fragmenttype:
226
            ret = ret = "%s Fragment Type:<strong>%s</strong><br/>" %(ret, self.fragmenttype)
227
        if self.icmpcode:
228
            ret = ret = "%s ICMP code:<strong>%s</strong><br/>" %(ret, self.icmpcode)
229
        if self.icmptype:
230
            ret = ret = "%s ICMP Type:<strong>%s</strong><br/>" %(ret, self.icmptype)
231
        if self.packetlength:
232
            ret = ret = "%s Packet Length:<strong>%s</strong><br/>" %(ret, self.packetlength)
233
        if self.protocol:
234
            ret = ret = "%s Protocol:<strong>%s</strong><br/>" %(ret, self.protocol)
235
        if self.source:
236
            ret = ret = "%s Source Address:<strong>%s</strong><br/>" %(ret, self.source)
237
        if self.tcpflag:
238
            ret = ret = "%s TCP flag:<strong>%s</strong><br/>" %(ret, self.tcpflag)
239
        if self.port:
240
            for port in self.port.all():
255 241
                    ret = "%s Port:<strong>%s</strong><br/>" %(ret, port)
256
        if match.matchDestinationPort:
257
            for port in match.matchDestinationPort.all():
242
        if self.destinationport:
243
            for port in self.destinationport.all():
258 244
                    ret = "%s Port:<strong>%s</strong><br/>" %(ret, port)
259
        if match.matchSourcePort:
260
            for port in match.matchSourcePort.all():
245
        if self.sourceport:
246
            for port in self.sourceport.all():
261 247
                    ret = "%s Port:<strong>%s</strong><br/>" %(ret, port)
262
        if match.matchdscp:
263
            for dscp in match.matchdscp.all():
248
        if self.dscp:
249
            for dscp in self.dscp.all():
264 250
                    ret = "%s Port:<strong>%s</strong><br/>" %(ret, dscp)
265 251
        return ret.rstrip('<br/>')
266 252
        
b/utils/proxy.py
66 66
            flow.routes.append(route)
67 67
            device.routing_options.append(flow)
68 68
            route.name = route_obj.name
69
            match = route_obj.match
70
            if match.matchSource:
71
                route.match['source'].append(match.matchSource.address)
72
            if match.matchDestination:
73
                route.match['destination'].append(match.matchDestination.address)
74
            if match.matchprotocol:
75
                route.match['protocol'].append(match.matchprotocol.protocol)
76
            if match.matchport:
77
                for port in match.matchport.all():
78
                    route.match['port'].append(port.port)
79
            if match.matchDestinationPort:
80
                for port in match.matchDestinationPort.all():
81
                    route.match['destination-port'].append(port.port)
82
            if match.matchSourcePort:
83
                for port in match.matchSourcePort.all():
84
                    route.match['source-port'].append(port.port)
85
            if match.matchicmpcode:
86
                route.match['icmp-code'].append(match.matchicmpcode.icmp_code)
87
            if match.matchicmptype:
88
                route.match['icmp-type'].append(match.matchicmptype.icmp_type)
89
            if match.matchTcpFlag:
90
                route.match['tcp-flags'].append(match.matchTcpFlag.tcp_flags)
91
            if match.matchdscp:
92
                for dscp in match.matchdscp.all():
93
                    route.match['dscp'].append(dscp.dscp)
94
            if match.matchfragmenttype:
95
                route.match['fragment'].append(match.matchfragmenttype.fragmenttype)
96
            then = route_obj.then
97
            for thenaction in then.thenaction.all():
69
            if route_obj.source:
70
                route.match['source'].append(route_obj.source)
71
            if route_obj.destination:
72
                route.match['destination'].append(route_obj.destination)
73
            if route_obj.protocol:
74
                route.match['protocol'].append(route_obj.protocol)
75
            try:
76
                if route_obj.port:
77
                    for port in route_obj.port.all():
78
                        route.match['port'].append(port.port)
79
            except:
80
                pass
81
            try:
82
                if route_obj.destinationport:
83
                    for port in route_obj.destinationport.all():
84
                        route.match['destination-port'].append(port.port)
85
            except:
86
                pass
87
            try:
88
                if route_obj.sourceport:
89
                    for port in route_obj.sourceport.all():
90
                        route.match['source-port'].append(port.port)
91
            except:
92
                pass
93
            if route_obj.icmpcode:
94
                route.match['icmp-code'].append(route_obj.icmpcode)
95
            if route_obj.icmptype:
96
                route.match['icmp-type'].append(route_obj.icmptype)
97
            if route_obj.tcpflag:
98
                route.match['tcp-flags'].append(route_obj.tcpflag)
99
            try:
100
                if route_obj.dscp:
101
                    for dscp in route_obj.dscp.all():
102
                        route.match['dscp'].append(dscp.dscp)
103
            except:
104
                pass
105
            if route_obj.fragmenttype:
106
                route.match['fragment'].append(route_obj.fragmenttype)
107
            for thenaction in route_obj.then.all():
98 108
                if thenaction.action_value:
99 109
                    route.then[thenaction.action] = thenaction.action_value
100 110
                else:

Also available in: Unified diff