Example #1
0
 def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated):
     ofmsgs = []
     if is_updated:
         self.logger.info(
             'Updating next hop for route %s via %s (%s) on VLAN %u' %
             (ip_dst, ip_gw, eth_dst, vlan.vid))
         ofmsgs.extend(self._del_route_flows(vlan, ip_dst))
     else:
         self.logger.info('Adding new route %s via %s (%s) on VLAN %u' %
                          (ip_dst, ip_gw, eth_dst, vlan.vid))
     if self.use_group_table:
         inst = [
             valve_of.apply_actions([
                 valve_of.group_act(
                     group_id=self._group_id_from_ip_gw(vlan, ip_gw))
             ])
         ]
     else:
         inst = [
             valve_of.apply_actions(self._nexthop_actions(eth_dst, vlan)),
             valve_of.goto_table(self.eth_dst_table)
         ]
     for routed_vlan in self._routed_vlans(vlan):
         in_match = self._route_match(routed_vlan, ip_dst)
         ofmsgs.append(
             self.fib_table.flowmod(in_match,
                                    priority=self._route_priority(ip_dst),
                                    inst=inst))
     return ofmsgs
Example #2
0
 def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated):
     ofmsgs = []
     in_match = self.valve_in_match(self.fib_table,
                                    vlan=vlan,
                                    eth_type=self._eth_type(),
                                    nw_dst=ip_dst)
     prefixlen = ipaddr.IPNetwork(ip_dst).prefixlen
     priority = self.route_priority + prefixlen
     if is_updated:
         self.logger.info('Updating next hop for route %s via %s (%s)',
                          ip_dst, ip_gw, eth_dst)
         ofmsgs.extend(
             self.valve_flowdel(self.fib_table, in_match,
                                priority=priority))
     else:
         self.logger.info('Adding new route %s via %s (%s)', ip_dst, ip_gw,
                          eth_dst)
     if self.use_group_table:
         inst = [
             valve_of.apply_actions([
                 valve_of.group_act(group_id=self.ip_gw_to_group_id[ip_gw])
             ])
         ]
     else:
         inst = [
             valve_of.apply_actions(self._nexthop_actions(eth_dst)),
             valve_of.goto_table(self.eth_dst_table)
         ]
     ofmsgs.append(
         self.valve_flowmod(self.fib_table,
                            in_match,
                            priority=priority,
                            inst=inst))
     return ofmsgs
Example #3
0
def build_output_actions(output_dict):
    """Implement actions to alter packet/output."""
    output_actions = []
    output_port = None
    ofmsgs = []
    # if destination rewriting selected, rewrite it.
    if 'dl_dst' in output_dict:
        output_actions.append(valve_of.set_eth_dst(output_dict['dl_dst']))
    # rewrite any VLAN headers.
    vlan_actions = rewrite_vlan(output_dict)
    if vlan_actions:
        output_actions.extend(vlan_actions)
    if 'port' in output_dict:
        output_port = output_dict['port']
        output_actions.append(valve_of.output_port(output_port))
    if 'failover' in output_dict:
        failover = output_dict['failover']
        group_id = failover['group_id']
        buckets = []
        for port in failover['ports']:
            buckets.append(
                valve_of.bucket(watch_port=port,
                                actions=[valve_of.output_port(port)]))
        ofmsgs.append(valve_of.groupdel(group_id=group_id))
        ofmsgs.append(valve_of.groupadd_ff(group_id=group_id, buckets=buckets))
        output_actions.append(valve_of.group_act(group_id=group_id))
    return (output_port, output_actions, ofmsgs)
Example #4
0
 def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated):
     ofmsgs = []
     if self.routers:
         in_match = self._route_match(AnyVlan(), ip_dst)
     else:
         in_match = self._route_match(vlan, ip_dst)
     if is_updated:
         self.logger.info('Updating next hop for route %s via %s (%s)',
                          ip_dst, ip_gw, eth_dst)
         ofmsgs.extend(self._del_route_flows(vlan, ip_dst))
     else:
         self.logger.info('Adding new route %s via %s (%s)', ip_dst, ip_gw,
                          eth_dst)
     if self.use_group_table:
         inst = [
             valve_of.apply_actions([
                 valve_of.group_act(group_id=self.ip_gw_to_group_id[ip_gw])
             ])
         ]
     else:
         inst = [
             valve_of.apply_actions(self._nexthop_actions(eth_dst, vlan)),
             valve_of.goto_table(self.eth_dst_table)
         ]
     ofmsgs.append(
         self.valve_flowmod(self.fib_table,
                            in_match,
                            priority=self._route_priority(ip_dst),
                            inst=inst))
     return ofmsgs
Example #5
0
 def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated=None):
     ofmsgs = []
     if is_updated is not None:
         in_match = self.valve_in_match(
             self.fib_table, vlan=vlan,
             eth_type=self._eth_type(), nw_dst=ip_dst)
         prefixlen = ipaddr.IPNetwork(ip_dst).prefixlen
         priority = self.route_priority + prefixlen
         if is_updated:
             self.logger.info(
                 'Updating next hop for route %s via %s (%s)',
                 ip_dst, ip_gw, eth_dst)
             ofmsgs.extend(self.valve_flowdel(
                 self.fib_table,
                 in_match,
                 priority=priority))
         else:
             self.logger.info(
                 'Adding new route %s via %s (%s)',
                 ip_dst, ip_gw, eth_dst)
         if self.use_group_table:
             inst = [valve_of.apply_actions([valve_of.group_act(
                 group_id=self.ip_gw_to_group_id[ip_gw])])]
         else:
             inst = [valve_of.apply_actions(self._nexthop_actions(eth_dst)),
                     valve_of.goto_table(self.eth_dst_table)]
         ofmsgs.append(self.valve_flowmod(
             self.fib_table,
             in_match,
             priority=priority,
             inst=inst))
     return ofmsgs
Example #6
0
 def _build_group_flood_rules(self, vlan, modify, command):
     flood_priority = self.flood_priority
     broadcast_group = self.groups.get_entry(
         vlan.vid, self._build_group_buckets(vlan, False))
     unicast_group = self.groups.get_entry(
         vlan.vid + valve_of.VLAN_GROUP_OFFSET,
         self._build_group_buckets(vlan, vlan.unicast_flood))
     ofmsgs = []
     if modify:
         ofmsgs.append(broadcast_group.modify())
         ofmsgs.append(unicast_group.modify())
     else:
         ofmsgs.extend(broadcast_group.add())
         ofmsgs.extend(unicast_group.add())
     for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
         if unicast_eth_dst and not vlan.unicast_flood:
             continue
         group = broadcast_group
         if not eth_dst:
             group = unicast_group
         match = self.flood_table.match(vlan=vlan,
                                        eth_dst=eth_dst,
                                        eth_dst_mask=eth_dst_mask)
         ofmsgs.append(
             self.flood_table.flowmod(
                 match=match,
                 command=command,
                 inst=[
                     valve_of.apply_actions(
                         [valve_of.group_act(group.group_id)])
                 ],
                 priority=flood_priority))
         flood_priority += 1
     return ofmsgs
Example #7
0
    def build_flood_rules(self, vlan, modify=False):
        """Add flows to flood packets to unknown destinations on a VLAN."""
        # TODO: not all vendors implement groups well.
        # That means we need flood rules for each input port, outputting
        # to all ports except the input port. When all vendors implement
        # groups correctly we can use them.
        command = ofp.OFPFC_ADD
        group_mod_method = valve_of.groupadd
        if modify:
            command = ofp.OFPFC_MODIFY_STRICT
            group_mod_method = valve_of.groupmod
        flood_priority = self.flood_priority
        ofmsgs = []
        broadcast_buckets = []
        unicast_buckets = []
        if self.use_group_table and self.stack is None:
            # Group table usage is not supported for stacking yet
            # TODO: implement stacking using group table
            broadcast_buckets = self._build_group_buckets(vlan, False)
            unicast_buckets = self._build_group_buckets(vlan, vlan.unicast_flood)
            group_id = vlan.vid
            ofmsgs.append(group_mod_method(
                group_id=group_id,
                buckets=broadcast_buckets))
            ofmsgs.append(group_mod_method(
                group_id=group_id+valve_of.VLAN_GROUP_OFFSET,
                buckets=unicast_buckets))
            for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
                if unicast_eth_dst and not vlan.unicast_flood:
                    continue
                group_id = vlan.vid
                if not eth_dst:
                    group_id = group_id + valve_of.VLAN_GROUP_OFFSET
                match = self.valve_in_match(
                    self.flood_table, vlan=vlan,
                    eth_dst=eth_dst, eth_dst_mask=eth_dst_mask)
                ofmsgs.append(self.valve_flowmod(
                    self.flood_table,
                    match=match,
                    command=command,
                    inst=[valve_of.apply_actions([valve_of.group_act(group_id)])],
                    priority=flood_priority))
                flood_priority += 1
        else:
            for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
                if unicast_eth_dst and not vlan.unicast_flood:
                    continue
                ofmsgs.extend(self._build_unmirrored_flood_rules(
                    vlan, eth_dst, eth_dst_mask,
                    unicast_eth_dst, command, flood_priority))
                flood_priority += 1
                ofmsgs.extend(self._build_mirrored_flood_rules(
                    vlan, eth_dst, eth_dst_mask,
                    unicast_eth_dst, command, flood_priority))
                flood_priority += 1

        return ofmsgs
Example #8
0
    def build_flood_rules(self, vlan, modify=False):
        """Add flows to flood packets to unknown destinations on a VLAN."""
        # TODO: not all vendors implement groups well.
        # That means we need flood rules for each input port, outputting
        # to all ports except the input port. When all vendors implement
        # groups correctly we can use them.
        command = ofp.OFPFC_ADD
        group_mod_method = valve_of.groupadd
        if modify:
            command = ofp.OFPFC_MODIFY_STRICT
            group_mod_method = valve_of.groupmod
        flood_priority = self.flood_priority
        ofmsgs = []
        broadcast_buckets = []
        unicast_buckets = []
        if self.use_group_table and self.stack is None:
            # Group table usage is not supported for stacking yet
            # TODO: implement stacking using group table
            broadcast_buckets = self._build_group_buckets(vlan, False)
            unicast_buckets = self._build_group_buckets(vlan, vlan.unicast_flood)
            group_id = vlan.vid
            ofmsgs.append(group_mod_method(
                group_id=group_id,
                buckets=broadcast_buckets))
            ofmsgs.append(group_mod_method(
                group_id=group_id+valve_of.VLAN_GROUP_OFFSET,
                buckets=unicast_buckets))
            for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
                if unicast_eth_dst and not vlan.unicast_flood:
                    continue
                group_id = vlan.vid
                if not eth_dst:
                    group_id = group_id + valve_of.VLAN_GROUP_OFFSET
                match = self.valve_in_match(
                    self.flood_table, vlan=vlan,
                    eth_dst=eth_dst, eth_dst_mask=eth_dst_mask)
                ofmsgs.append(self.valve_flowmod(
                    self.flood_table,
                    match=match,
                    command=command,
                    inst=[valve_of.apply_actions([valve_of.group_act(group_id)])],
                    priority=flood_priority))
                flood_priority += 1
        else:
            for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
                if unicast_eth_dst and not vlan.unicast_flood:
                    continue
                ofmsgs.extend(self._build_unmirrored_flood_rules(
                    vlan, eth_dst, eth_dst_mask,
                    unicast_eth_dst, command, flood_priority))
                flood_priority += 1
                ofmsgs.extend(self._build_mirrored_flood_rules(
                    vlan, eth_dst, eth_dst_mask,
                    unicast_eth_dst, command, flood_priority))
                flood_priority += 1

        return ofmsgs
Example #9
0
 def _build_group_flood_rules(self, vlan, modify, command):
     flood_priority = self.flood_priority
     broadcast_buckets = self._build_group_buckets(vlan, False)
     unicast_buckets = self._build_group_buckets(vlan, vlan.unicast_flood)
     group_id = vlan.vid
     ofmsgs = []
     group_mod_method = valve_of.groupadd
     if modify:
         group_mod_method = valve_of.groupmod
     else:
         ofmsgs.append(valve_of.groupdel(group_id=group_id))
         ofmsgs.append(
             valve_of.groupdel(group_id=group_id +
                               valve_of.VLAN_GROUP_OFFSET))
     ofmsgs.append(
         group_mod_method(group_id=group_id, buckets=broadcast_buckets))
     ofmsgs.append(
         group_mod_method(group_id=group_id + valve_of.VLAN_GROUP_OFFSET,
                          buckets=unicast_buckets))
     for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS:
         if unicast_eth_dst and not vlan.unicast_flood:
             continue
         group_id = vlan.vid
         if not eth_dst:
             group_id = group_id + valve_of.VLAN_GROUP_OFFSET
         match = self.valve_in_match(self.flood_table,
                                     vlan=vlan,
                                     eth_dst=eth_dst,
                                     eth_dst_mask=eth_dst_mask)
         ofmsgs.append(
             self.valve_flowmod(self.flood_table,
                                match=match,
                                command=command,
                                inst=[
                                    valve_of.apply_actions(
                                        [valve_of.group_act(group_id)])
                                ],
                                priority=flood_priority))
         flood_priority += 1
     return ofmsgs