Ejemplo n.º 1
0
    def update_policy(self, pkt):
        if self.group_by:  # MATCH ON PROVIDED GROUP_BY
            pred = match([(field, pkt[field]) for field in self.group_by])
        else:  # OTHERWISE, MATCH ON ALL AVAILABLE GROUP_BY
            pred = match([(field, pkt[field]) for field in pkt.available_group_by()])
        # INCREMENT THE NUMBER OF TIMES MATCHING PKT SEEN
        try:
            self.seen[pred] += 1
        except KeyError:
            self.seen[pred] = 1

        if self.seen[pred] == self.limit:
            val = {h: pkt[h] for h in self.group_by}
            self.done.append(match(val))
            self.policy = ~union(self.done)
Ejemplo n.º 2
0
 def _commute_test(self, act, pkts):
     from pyretic.core.language import modify, drop, identity, Controller, CountBucket, DerivedPolicy, match
     while isinstance(act, DerivedPolicy):
         act = act.policy
     if act == identity:
         return pkts
     elif act == drop:
         return drop
     elif act == Controller or isinstance(act, CountBucket):
         return identity
     elif isinstance(act, modify):
         new_match_dict = {}
         if pkts == identity:
             return identity
         elif pkts == drop:
             return drop
         for f, v in pkts.map.iteritems():
             if f in act.map and act.map[f] == v:
                 continue
             elif f in act.map and act.map[f] != v:
                 return drop
             else:
                 new_match_dict[f] = v
         if len(new_match_dict) == 0:
             return identity
         return match(**new_match_dict)
     else:
         # TODO (cole) use compile error.
         # TODO (cole) what actions are allowable?
         raise TypeError
Ejemplo n.º 3
0
 def _commute_test(act, pkts):
     while isinstance(act, DerivedPolicy):
         act = act.policy
     if act == identity:
         return pkts
     elif act == Controller or isinstance(act, CountBucket):
         return identity
     elif isinstance(act, modify):
         new_match_dict = {}
         if pkts == identity:
             return identity
         elif pkts == drop:
             return drop
         for f, v in pkts.map.iteritems():
             if f in act.map and act.map[f] == v:
                 continue
             elif f in act.map and act.map[f] != v:
                 return drop
             else:
                 new_match_dict[f] = v
         if len(new_match_dict) == 0:
             return identity
         return match(**new_match_dict)
     else:
         raise TypeError
Ejemplo n.º 4
0
    def update_policy(self, pkt):
        if self.group_by:  # MATCH ON PROVIDED GROUP_BY
            pred = match([(field, pkt[field]) for field in self.group_by])
        else:  # OTHERWISE, MATCH ON ALL AVAILABLE GROUP_BY
            pred = match([(field, pkt[field])
                          for field in pkt.available_group_by()])
        # INCREMENT THE NUMBER OF TIMES MATCHING PKT SEEN
        try:
            self.seen[pred] += 1
        except KeyError:
            self.seen[pred] = 1

        if self.seen[pred] == self.limit:
            val = {h: pkt[h] for h in self.group_by}
            self.done.append(match(val))
            self.policy = ~union(self.done)
Ejemplo n.º 5
0
    def _commute_test(self, act, pkts):
        from pyretic.core.language import modify, drop, identity, Controller, CountBucket, DerivedPolicy, match

        while isinstance(act, DerivedPolicy):
            act = act.policy
        if act == identity:
            return pkts
        elif act == drop:
            return drop
        elif act == Controller or isinstance(act, CountBucket):
            return identity
        elif isinstance(act, modify):
            new_match_dict = {}
            if pkts == identity:
                return identity
            elif pkts == drop:
                return drop
            for f, v in pkts.map.iteritems():
                if f in act.map and act.map[f] == v:
                    continue
                elif f in act.map and act.map[f] != v:
                    return drop
                else:
                    new_match_dict[f] = v
            if len(new_match_dict) == 0:
                return identity
            return match(**new_match_dict)
        else:
            # TODO (cole) use compile error.
            # TODO (cole) what actions are allowable?
            raise TypeError
Ejemplo n.º 6
0
 def use_explicit_switches(pol):
     """ Ensure every switch in the network gets reflected in the policy
     sent to netkat. This is because netkat generates a separate copy of
     the policy per switch, and it is necessary for it to know that a switch
     appears in the policy through the policy itself."""
     from pyretic.core.language import match, identity
     pred_policy = None
     used_cnt = switch_cnt if switch_cnt else 0
     for i in range(1, used_cnt + 1):
         if pred_policy is None:
             pred_policy = match(switch = i)
         else:
             pred_policy |= match(switch = i)
     if pred_policy is None:
         pred_policy = identity
     return pred_policy >> pol
Ejemplo n.º 7
0
def _commute_test(act, pkts):
    from pyretic.core.language import (match, modify, drop, identity,
                                       Controller, CountBucket,
                                       DerivedPolicy, PathBucket)
    from pyretic.lib.netflow import NetflowBucket
    while isinstance(act, DerivedPolicy):
        act = act.policy
    if act == identity:
        return pkts
    elif (act == Controller or isinstance(act, PathBucket) or
          isinstance(act, NetflowBucket)):
        return identity
    elif isinstance(act, CountBucket):
        """ TODO(ngsrinivas): inspect which possibility is best """
        return identity
        # return pkts
    elif isinstance(act, modify):
        new_match_dict = {}
        if pkts == identity:
            return identity
        elif pkts == drop:
            return drop
        for f, v in pkts.map.iteritems():
            if f in act.map and act.map[f] == v:
                continue
            elif f in act.map and act.map[f] != v:
                return drop
            else:
                new_match_dict[f] = v
        if len(new_match_dict) == 0:
            return identity
        return match(**new_match_dict)
    else:
        raise TypeError
Ejemplo n.º 8
0
 def set_network(self, network):
     super(egress_network,self).set_network(network)
     updated_egresses = network.topology.egress_locations()
     if not self.egresses == updated_egresses:
         self.egresses = updated_egresses
         self.policy = parallel([match(switch=l.switch,
                                    outport=l.port_no) 
                              for l in self.egresses])
Ejemplo n.º 9
0
 def set_network(self, network):
     super(ingress_network, self).set_network(network)
     updated_egresses = network.topology.egress_locations()
     if not self.egresses == updated_egresses:
         self.egresses = updated_egresses
         self.policy = parallel([
             match(switch=l.switch, inport=l.port_no) for l in self.egresses
         ])
Ejemplo n.º 10
0
        def eval(self,pkt):
            if not self.limit is None:
                if self.group_by:    # MATCH ON PROVIDED GROUP_BY
                    pred = match([(field,pkt[field]) for field in self.group_by])
                else:              # OTHERWISE, MATCH ON ALL AVAILABLE GROUP_BY
                    pred = match([(field,pkt[field]) 
                                  for field in pkt.available_group_by()])
                # INCREMENT THE NUMBER OF TIMES MATCHING PKT SEEN
                try:
                    self.seen[pred] += 1
                except KeyError:
                    self.seen[pred] = 1

                if self.seen[pred] > self.limit:
                    return set()
            self.fwd_bucket.eval(pkt)
            return {pkt}
Ejemplo n.º 11
0
        def eval(self, pkt):
            if not self.limit is None:
                if self.group_by:  # MATCH ON PROVIDED GROUP_BY
                    pred = match([(field, pkt[field])
                                  for field in self.group_by])
                else:  # OTHERWISE, MATCH ON ALL AVAILABLE GROUP_BY
                    pred = match([(field, pkt[field])
                                  for field in pkt.available_group_by()])
                # INCREMENT THE NUMBER OF TIMES MATCHING PKT SEEN
                try:
                    self.seen[pred] += 1
                except KeyError:
                    self.seen[pred] = 1

                if self.seen[pred] > self.limit:
                    return set()
            self.fwd_bucket.eval(pkt)
            return {pkt}
Ejemplo n.º 12
0
 def update_aggregate(self,pkt):
     if self.group_by:
         from pyretic.core.language import match
         groups = set(self.group_by) & set(pkt.available_fields())
         pred = match([(field,pkt[field]) for field in groups])
         try:
             self.aggregate[pred] = self.aggregator(self.aggregate[pred],pkt)
         except KeyError:
             self.aggregate[pred] = self.aggregator(0,pkt)
     else:
         self.aggregate = self.aggregator(self.aggregate,pkt)
Ejemplo n.º 13
0
 def update_aggregate(self,pkt):
     if self.group_by:
         from pyretic.core.language import match
         groups = set(self.group_by) & set(pkt.available_fields())
         pred = match([(field,pkt[field]) for field in groups])
         try:
             self.aggregate[pred] = self.aggregator(self.aggregate[pred],pkt)
         except KeyError:
             self.aggregate[pred] = self.aggregator(0,pkt)
     else:
         self.aggregate = self.aggregator(self.aggregate,pkt)
Ejemplo n.º 14
0
    def update_policy(self, pkt):
        pred = self.get_pred_from_pkt(pkt)
        # INCREMENT THE NUMBER OF TIMES MATCHING PKT SEEN
        try:
            self.seen[pred] += 1
        except KeyError:
            self.seen[pred] = 1

        if self.seen[pred] == self.limit:
            val = {h: pkt[h] for h in self.group_by}
            self.done.append(match(val))
            self.policy = ~union(self.done)
Ejemplo n.º 15
0
    def update_policy(self,pkt):
        pred = self.get_pred_from_pkt(pkt)
        # INCREMENT THE NUMBER OF TIMES MATCHING PKT SEEN
        try:
            self.seen[pred] += 1
        except KeyError:
            self.seen[pred] = 1

        if self.seen[pred] == self.limit:
            val = {h : pkt[h] for h in self.group_by}
            self.done.append(match(val))
            self.policy = ~union(self.done)
Ejemplo n.º 16
0
def create_match(pattern, switch_id, vlan_offset_nbits):
    from pyretic.core.language import match

    def __reverse_mac__(m):
        return ':'.join(m.split(':')[::-1])

    if switch_id > 0:
        match_map = {'switch': switch_id}
    else:
        match_map = {}
    vlan_processed = False
    for k, v in pattern.items():
        if v is not None:
            if k == 'dlSrc' or k == 'dlDst':
                """ TODO: NetKat returns MAC addresses reversed. """
                match_map[field_map[k]] = MAC(__reverse_mac__(v))
            elif k == 'dlVlan' or k == 'dlVlanPcp':
                """ Reset `None` value for VLAN matches, if any. """
                if not vlan_processed:
                    if (('dlVlan' in pattern
                         and pattern['dlVlan'] == VLAN_NONE_VALUE) and
                        ('dlVlanPcp' in pattern
                         and pattern['dlVlanPcp'] == VLAN_PCP_NONE_VALUE)):
                        match_map['vlan_id'] = None
                        match_map['vlan_pcp'] = None
                    else:

                        def get_num(v):
                            # HACK! Sometimes, one of the fields has a value
                            # `None`. TODO: Must understand why this happens,
                            # because the compiler/runtime always set vlan_id
                            # and vlan_pcp together. May well lead to bugs in
                            # future!
                            return v if not v is None else 0

                        match_map['vlan_id'] = get_num(pattern['dlVlan'])
                        match_map['vlan_pcp'] = get_num(pattern['dlVlanPcp'])
                    vlan_processed = True
            else:
                match_map[field_map[k]] = v

    # HACK! NetKat doesn't return vlan_pcp with vlan_id sometimes.
    if 'vlan_id' in match_map and not 'vlan_pcp' in match_map:
        match_map['vlan_pcp'] = 0
    # Add auxiliary information for VLAN matches
    if 'vlan_id' in match_map:
        match_map['vlan_offset'] = vlan_offset_nbits['vlan_offset']
        match_map['vlan_nbits'] = vlan_offset_nbits['vlan_nbits']
        match_map['vlan_total_stages'] = vlan_offset_nbits['vlan_total_stages']
    # Ensure both id and pcp are set by the time we return match.
    assert (not 'vlan_id' in match_map) or 'vlan_pcp' in match_map
    assert (not 'vlan_pcp' in match_map) or 'vlan_id' in match_map
    return match(**match_map)
Ejemplo n.º 17
0
 def track_eval(self, pkt, dry):
     """Don't look any more such packets"""
     eval_trace = EvalTrace(self)
     (results, trace) = self.policy.track_eval(pkt, dry)
     eval_trace.add_trace(trace)
     if results:
         if not dry:
             (results, trace) = self.pwfb.track_eval(pkt, dry)
             eval_trace.add_trace(trace)
             if not results:
                 val = {h: pkt[h] for h in self.group_by}
                 self.policy = ~match(val) & self.policy
         else:
             eval_trace.add_trace(EvalTrace(self.pwfb))
     return (set(), eval_trace)
Ejemplo n.º 18
0
 def track_eval(self,pkt,dry):
     """Don't look any more such packets"""
     eval_trace = EvalTrace(self)
     (results,trace) = self.policy.track_eval(pkt,dry)
     eval_trace.add_trace(trace)
     if results: 
         if not dry:
             (results,trace) = self.pwfb.track_eval(pkt,dry)
             eval_trace.add_trace(trace)
             if not results:
                 val = {h : pkt[h] for h in self.group_by}
                 self.policy = ~match(val) & self.policy
         else:
             eval_trace.add_trace(EvalTrace(self.pwfb))
     return (set(),eval_trace)
Ejemplo n.º 19
0
def create_match(pattern, switch_id, vlan_offset_nbits):
    from pyretic.core.language import match
    def __reverse_mac__(m):
        return ':'.join(m.split(':')[::-1])
    if switch_id > 0:
        match_map = {'switch' : switch_id}
    else:
        match_map = {}
    vlan_processed = False
    for k,v in pattern.items():
        if v is not None:
            if k == 'dlSrc' or k == 'dlDst':
                """ TODO: NetKat returns MAC addresses reversed. """
                match_map[field_map[k]] = MAC(__reverse_mac__(v))
            elif k == 'dlVlan' or k == 'dlVlanPcp':
                """ Reset `None` value for VLAN matches, if any. """
                if not vlan_processed:
                    if (('dlVlan' in pattern and pattern['dlVlan'] == VLAN_NONE_VALUE) and
                        ('dlVlanPcp' in pattern and pattern['dlVlanPcp'] == VLAN_PCP_NONE_VALUE)):
                        match_map['vlan_id'] = None
                        match_map['vlan_pcp'] = None
                    else:
                        def get_num(v):
                            # HACK! Sometimes, one of the fields has a value
                            # `None`. TODO: Must understand why this happens,
                            # because the compiler/runtime always set vlan_id
                            # and vlan_pcp together. May well lead to bugs in
                            # future!
                            return v if not v is None else 0
                        match_map['vlan_id'] = get_num(pattern['dlVlan'])
                        match_map['vlan_pcp'] = get_num(pattern['dlVlanPcp'])
                    vlan_processed = True
            else:
                match_map[field_map[k]] = v

    # HACK! NetKat doesn't return vlan_pcp with vlan_id sometimes.
    if 'vlan_id' in match_map and not 'vlan_pcp' in match_map:
        match_map['vlan_pcp'] = 0
    # Add auxiliary information for VLAN matches
    if 'vlan_id' in match_map:
        match_map['vlan_offset'] = vlan_offset_nbits['vlan_offset']
        match_map['vlan_nbits'] = vlan_offset_nbits['vlan_nbits']
        match_map['vlan_total_stages'] = vlan_offset_nbits['vlan_total_stages']
    # Ensure both id and pcp are set by the time we return match.
    assert (not 'vlan_id' in match_map) or 'vlan_pcp' in match_map
    assert (not 'vlan_pcp' in match_map) or 'vlan_id' in match_map
    return match(**match_map)
Ejemplo n.º 20
0
 def set_network(self, network):
     changed = False
     super(flood,self).set_network(network) 
     if not network is None:
         updated_mst = Topology.minimum_spanning_tree(network.topology)
         if not self.mst is None:
             if self.mst != updated_mst:
                 self.mst = updated_mst
                 changed = True
         else:
             self.mst = updated_mst
             changed = True
     if changed:
         self.policy = parallel([
                 match(switch=switch) >>
                     parallel(map(xfwd,attrs['ports'].keys()))
                 for switch,attrs in self.mst.nodes(data=True)])
Ejemplo n.º 21
0
 def set_network(self, network):
     changed = False
     super(flood, self).set_network(network)
     if not network is None:
         updated_mst = Topology.minimum_spanning_tree(network.topology)
         if not self.mst is None:
             if self.mst != updated_mst:
                 self.mst = updated_mst
                 changed = True
         else:
             self.mst = updated_mst
             changed = True
     if changed:
         self.policy = parallel([
             match(switch=switch) >> parallel(
                 map(xfwd, attrs['ports'].keys()))
             for switch, attrs in self.mst.nodes(data=True)
         ])
Ejemplo n.º 22
0
    def __init__(self, time_window, **kwargs):
        super(visited,self).__init__()
        loggername = "netassay." + self.__class__.__name__
        logging.getLogger(loggername).info("__init__(): called")
        self.logger = logging.getLogger(loggername)
        self.naw = NetAssayWindow.get_instance()

        self.time_window = time_window
        self.kwargs_filter = match(**kwargs)
        
        self.visit_list = []
        self.timer = None

        self.important_pkts = packets(1, ['srcmac', 'dstmac', 'srcip', 'dstip', 'srcport', 'dstport', 'protocol'])
        self.important_pkts.register_callback(self._pkt_callback)
        self.registered_rule = self.kwargs_filter >> self.important_pkts

        self.naw.register_forwarding_rule(self.registered_rule)
Ejemplo n.º 23
0
def create_match(pattern, switch_id):
    from pyretic.core.language import match
    def __reverse_mac__(m):
        return ':'.join(m.split(':')[::-1])
    if switch_id > 0:
        match_map = {'switch' : switch_id}
    else:
        match_map = {}
    for k,v in pattern.items():
        if v is not None:
            if k == 'dlSrc' or k == 'dlDst':
                """ TODO: NetKat returns MAC addresses reversed. """
                match_map[field_map[k]] = MAC(__reverse_mac__(v))
            else:
                match_map[field_map[k]] = v

    # HACK! NetKat doesn't return vlan_pcp with vlan_id sometimes.
    if 'vlan_id' in match_map and not 'vlan_pcp' in match_map:
        match_map['vlan_pcp'] = 0
    return match(**match_map)
Ejemplo n.º 24
0
 def __init__(self, outport):
     self.outport = outport
     super(fwd, self).__init__(
         if_(match(outport=-1), pop('outport')) >> push(
             outport=self.outport))
Ejemplo n.º 25
0
 def get_pred_from_pkt(self, pkt):
     if self.group_by:    # MATCH ON PROVIDED GROUP_BY
         return match([(field,pkt[field]) for field in self.group_by])
     else:              # OTHERWISE, MATCH ON ALL AVAILABLE GROUP_BY
         return match([(field,pkt[field])
                           for field in pkt.available_fields()])
Ejemplo n.º 26
0
 def __init__(self, field, group):
     self.group = group
     self.field = field
     super(_in, self).__init__(parallel([match({field: i}) for i in group]))
Ejemplo n.º 27
0
 def __init__(self,field,group):
     self.group = group
     self.field = field
     super(_in,self).__init__(union([match({field : i}) 
                             for i in group]))
Ejemplo n.º 28
0
 def eval(self,pkt):
     """Don't look any more such packets"""
     if self.policy.eval(pkt) and not self.pwfb.eval(pkt):
         val = {h : pkt[h] for h in self.group_by}
         self.policy = ~match(val) & self.policy
     return set()
Ejemplo n.º 29
0
def dum_policy(sdx, es):
    return (match(dstip=IP(dummyhostip), ethtype=ARP_TYPE) >> fwd(5)) + \
           (match(inport=5) >> parallel(
               [match(dstmac=mac) >> fwd(port.id_) for mac, port in sdx.mac_to_port.items()])
           ) + (match(dstip=IP(dummyhostip), ethtype=IP_TYPE, protocol=ICMP) >> EchoReciever(es))
Ejemplo n.º 30
0
 def __init__(self, field, match_val, mod_val):
     self.field = field
     self.match_val = match_val
     self.mod_val = mod_val
     super(match_modify,self).__init__(match(field=match_val) >>
                                       modify(field=mod_val))
Ejemplo n.º 31
0
def make_firewall_policy(config):
    print config
    # The rules list contains all of the individual rule entries.
    rules = []
    # Protocol constants from packet.
    both = (match(protocol=packet.TCP_PROTO, ethtype=packet.IPV4)
            | match(protocol=packet.UDP_PROTO, ethtype=packet.IPV4))
    tcp = match(protocol=packet.TCP_PROTO, ethtype=packet.IPV4)
    udp = match(protocol=packet.UDP_PROTO, ethtype=packet.IPV4)
    icmp = match(protocol=packet.ICMP_PROTO, ethtype=packet.IPV4)

    for entry in config:
        # The rules_items list contains all of the individual rule items.
        rule_items = []

        for key, value in entry.iteritems():
            if key != 'rulenum' and value != '-':
                if key == 'macaddr_src':
                    rule_items.append(match(srcmac=MAC(value)))
                elif key == 'macaddr_dst':
                    rule_items.append(match(dstmac=MAC(value)))
                elif key == 'ipaddr_src':
                    rule_items.append(match(srcip=IPAddr(value)))
                elif key == 'ipaddr_dst':
                    rule_items.append(match(dstip=IPAddr(value)))
                elif key == 'port_src':
                    rule_items.append(
                        match(srcport=int(value), ethtype=packet.IPV4))
                elif key == 'port_dst':
                    rule_items.append(
                        match(dstport=int(value), ethtype=packet.IPV4))
                elif key == 'protocol':
                    if value == 'T':
                        rule_items.append(tcp)
                    elif value == 'U':
                        rule_items.append(udp)
                    elif value == 'I':
                        rule_items.append(icmp)
                    elif value == 'B':
                        rule_items.append(both)
                elif key == 'ipproto':
                    rule_items.append(
                        match(protocol=int(value), ethtype=packet.IPV4))
        # Append only non-empty rules.
        if len(rule_items) > 0:
            rule = reduce(lambda x, y: x & y, rule_items)
            rules.append(rule)
        pass

    # Think about the following line.  What is it doing?
    # The line negates all traffic that matches the specified rules.
    allowed = ~(union(rules))

    print allowed

    return allowed
Ejemplo n.º 32
0
 def __init__(self, outport):
     self.outport = outport    
     super(xfwd,self).__init__((~match(inport=outport)) >> fwd(outport))
Ejemplo n.º 33
0
 def __init__(self, outport):
     self.outport = outport
     super(fwd,self).__init__(if_(match(outport=-1),pop('outport')) 
                              >> push(outport=self.outport))
Ejemplo n.º 34
0
 def get_pred_from_pkt(self, pkt):
     if self.group_by:  # MATCH ON PROVIDED GROUP_BY
         return match([(field, pkt[field]) for field in self.group_by])
     else:  # OTHERWISE, MATCH ON ALL AVAILABLE GROUP_BY
         return match([(field, pkt[field]) for field in pkt.available_fields()])
Ejemplo n.º 35
0
 def __init__(self, field, match_val, mod_val):
     self.field = field
     self.match_val = match_val
     self.mod_val = mod_val
     super(match_modify,
           self).__init__(match(field=match_val) >> modify(field=mod_val))
Ejemplo n.º 36
0
 def eval(self, pkt):
     """Don't look any more such packets"""
     if self.policy.eval(pkt) and not self.pwfb.eval(pkt):
         val = {h: pkt[h] for h in self.group_by}
         self.policy = ~match(val) & self.policy
     return set()
Ejemplo n.º 37
0
 def __init__(self, outport):
     self.outport = outport
     super(xfwd, self).__init__((~match(inport=outport)) >> fwd(outport))