def _gateway_traffic_redirect(self, net_info): if not self._is_ovs_extension(): return LOG.debug("redirecting gw traffic for net %s: %s", net_info, net_info.gateway_info) # similar rules will later be added to redirect the traffic # to each specific router MAC to br-mpls try: vlan = self.vlan_manager.get(net_info.id).vlan if net_info.gateway_info.mac: # there is a Neutron router on this network, so we won't # ARP spoof the gateway IP... self._disable_gw_arp_responder(vlan, net_info.gateway_info.ip) # but we will redirect traffic toward its MAC to br-mpls self._redirect_br_tun_to_mpls(net_info.gateway_info.mac, vlan) # we keep this one just in case VMs have a stale ARP entry # for the gateway IP: self._redirect_br_tun_to_mpls(bgpvpn_const.DEFAULT_GATEWAY_MAC, vlan) # when the OVS firewall driver is used, we can handle the # case where the gateway is directly connected to br-int: # traffic to the gateway MAC will be sent directly to br-tun # (ensuring that traffic that was already fallback'd is not # touched is done in setup_mpls_br) # (need push vlan because NORMAL will not be used, and hence # won't the vlan tag) flow = dict( table=ovs_agt_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE, priority=2, # before NORMAL action reg_net=vlan, dl_dst=net_info.gateway_info.mac, actions="push_vlan:0x8100,mod_vlan_vid:%d,output:%s" % (vlan, self.patch_int2tun)) ovs_fw.create_reg_numbers(flow) self.int_br.add_flow(**flow) else: # no Neutron router plugged, so ARP spoofing the # gateway IP is needed if not net_info.gateway_info.ip: LOG.warning("could not enable gw ARP responder for %s", net_info.id) return self._enable_gw_arp_responder(vlan, net_info.gateway_info.ip) self._redirect_br_tun_to_mpls(bgpvpn_const.DEFAULT_GATEWAY_MAC, vlan) except vlanmanager.MappingNotFound: LOG.warning( "no VLAN mapping for net %s, no gateway redirection " "in place", net_info.id)
def test_both_registers_defined(self): flow = {'foo': 'bar', 'reg_port': 1, 'reg_net': 2} expected_flow = {'foo': 'bar', 'reg{:d}'.format(ovsfw_consts.REG_PORT): 1, 'reg{:d}'.format(ovsfw_consts.REG_NET): 2} ovsfw.create_reg_numbers(flow) self.assertEqual(expected_flow, flow)
def test_all_registers_defined(self): flow = {'foo': 'bar', 'reg_port': 1, 'reg_net': 2, 'reg_remote_group': 3} expected_flow = {'foo': 'bar', 'reg{:d}'.format(ovsfw_consts.REG_PORT): 1, 'reg{:d}'.format(ovsfw_consts.REG_NET): 2, 'reg{:d}'.format(ovsfw_consts.REG_REMOTE_GROUP): 3} ovsfw.create_reg_numbers(flow) self.assertEqual(expected_flow, flow)
def _add_flow(self, **kwargs): dl_type = kwargs.get('dl_type') ovsfw.create_reg_numbers(kwargs) if isinstance(dl_type, int): kwargs['dl_type'] = "0x{:04x}".format(dl_type) LOG.debug("Add flow firewall log %s", str(kwargs)) if self._deferred: self.int_br.add_flow(**kwargs) else: self.int_br.br.add_flow(**kwargs)
def _stop_gateway_traffic_redirect(self, net_info, last_port=False, last_assoc=False): if not self._is_ovs_extension(): return if not net_info: return # if we are unplugging the last_port, we don't need to do # anything if there is no l3vpn for this network if last_port and not any([ assoc.bgpvpn.type == bgpvpn.BGPVPN_L3 for assoc in net_info.associations ]): return # if we have just removed the last l3vpn association for the network # then we don't need to do anything if there is no port on this network if last_assoc and len(net_info.ports) == 0: return try: vlan = self.vlan_manager.get(net_info.id).vlan if net_info.gateway_info.ip: self._disable_gw_arp_responder(vlan, net_info.gateway_info.ip) else: LOG.debug('no gw IP for %s, no ARP responder to disable', net_info.id) self._stop_redirect_br_tun_to_mpls(vlan) flow = dict( table=ovs_agt_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE, reg_net=vlan, ) ovs_fw.create_reg_numbers(flow) self.int_br.delete_flows(**flow) except vlanmanager.MappingNotFound: LOG.warning( "no VLAN mapping for net %s, could not disable gw " "redirection", net_info.id)
def test_no_registers_defined(self): flow = {'foo': 'bar'} ovsfw.create_reg_numbers(flow) self.assertEqual({'foo': 'bar'}, flow)
def _delete_flows(self, **kwargs): ovsfw.create_reg_numbers(kwargs) if self._deferred: self.int_br.delete_flows(**kwargs) else: self.int_br.br.delete_flows(**kwargs)