def _update_router_gw_info(self, context, router_id, info,
                               is_routes_update=False):
        router = self.plugin._get_router(context, router_id)
        org_ext_net_id = router.gw_port_id and router.gw_port.network_id
        org_enable_snat = router.enable_snat
        orgaddr, orgmask, orgnexthop = (
            self.plugin._get_external_attachment_info(
                context, router))

        super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
            context, router_id, info, router=router)

        new_ext_net_id = router.gw_port_id and router.gw_port.network_id
        new_enable_snat = router.enable_snat
        newaddr, newmask, newnexthop = (
            self.plugin._get_external_attachment_info(
                context, router))

        plr_id = self.edge_manager.get_plr_by_tlr_id(context, router_id)
        if not new_ext_net_id:
            if plr_id:
                # delete all plr relative conf
                self.edge_manager.delete_plr_by_tlr_id(
                    context, plr_id, router_id)
        else:
            # Connecting plr to the tlr if new_ext_net_id is not None.
            if not plr_id:
                plr_id = self.edge_manager.create_plr_with_tlr_id(
                    context, router_id, router.get('name'))
            if new_ext_net_id != org_ext_net_id and orgnexthop:
                # network changed, so need to remove default gateway
                # and all static routes before vnic can be configured
                edge_utils.clear_gateway(self.nsx_v, context, plr_id)

            # Update external vnic if addr or mask is changed
            if orgaddr != newaddr or orgmask != newmask:
                edge_utils.update_external_interface(
                    self.nsx_v, context, plr_id,
                    new_ext_net_id, newaddr, newmask)

            # Update SNAT rules if ext net changed
            # or ext net not changed but snat is changed.
            if (new_ext_net_id != org_ext_net_id or
                (new_ext_net_id == org_ext_net_id and
                 new_enable_snat != org_enable_snat)):
                self.plugin._update_nat_rules(context, router, plr_id)

            if (new_ext_net_id != org_ext_net_id or
                new_enable_snat != org_enable_snat or
                is_routes_update):
                # Open firewall flows on plr
                self.plugin._update_subnets_and_dnat_firewall(
                    context, router, router_id=plr_id)

        # update static routes in all
        self.update_routes(context, router_id, newnexthop)
        if self.plugin.metadata_proxy_handler:
            self._metadata_route_setup(context, router_id)
    def _update_router_gw_info(self, context, router_id, info,
                               is_routes_update=False):
        router = self.plugin._get_router(context, router_id)
        org_ext_net_id = router.gw_port_id and router.gw_port.network_id
        org_enable_snat = router.enable_snat
        orgaddr, orgmask, orgnexthop = (
            self.plugin._get_external_attachment_info(
                context, router))

        super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
            context, router_id, info, router=router)

        new_ext_net_id = router.gw_port_id and router.gw_port.network_id
        new_enable_snat = router.enable_snat
        newaddr, newmask, newnexthop = (
            self.plugin._get_external_attachment_info(
                context, router))

        edge_id = self._get_router_edge_id(context, router_id)
        with locking.LockManager.get_lock(edge_id, external=True):
            if new_ext_net_id != org_ext_net_id and orgnexthop:
                # network changed, so need to remove default gateway before
                # vnic can be configured
                LOG.debug("Delete default gateway %s", orgnexthop)
                edge_utils.clear_gateway(self.nsx_v, context, router_id)

            # Update external vnic if addr or mask is changed
            if orgaddr != newaddr or orgmask != newmask:
                edge_utils.update_external_interface(
                    self.nsx_v, context, router_id,
                    new_ext_net_id, newaddr, newmask)

            # Update SNAT rules if ext net changed
            # or ext net not changed but snat is changed.
            if (new_ext_net_id != org_ext_net_id or
                (new_ext_net_id == org_ext_net_id and
                 new_enable_snat != org_enable_snat)):
                self.plugin._update_nat_rules(context, router)

            if (new_ext_net_id != org_ext_net_id or
                new_enable_snat != org_enable_snat or
                is_routes_update):
                self.plugin._update_subnets_and_dnat_firewall(context, router)

            # Update static routes in all.
            self.plugin._update_routes(context, router_id, newnexthop)
    def _update_router_gw_info(self, context, router_id, info):
        router = self.plugin._get_router(context, router_id)
        edge_id = edge_utils.get_router_edge_id(context, router_id)
        if not edge_id:
            super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
                context, router_id, info, router=router)
        # UPDATE gw info only if the router has been attached to an edge
        else:
            is_migrated = False
            with locking.LockManager.get_lock(
                    str(edge_id),
                    lock_file_prefix=NSXV_ROUTER_RECONFIG,
                    external=True):
                router_ids = self.edge_manager.get_routers_on_same_edge(
                    context, router_id)
                org_ext_net_id = (router.gw_port_id and
                                  router.gw_port.network_id)
                org_enable_snat = router.enable_snat
                orgaddr, orgmask, orgnexthop = (
                    self.plugin._get_external_attachment_info(
                        context, router))
                super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
                    context, router_id, info, router=router)
                new_ext_net_id = (router.gw_port_id and
                                  router.gw_port.network_id)
                new_enable_snat = router.enable_snat
                newaddr, newmask, newnexthop = (
                    self.plugin._get_external_attachment_info(
                        context, router))
                if new_ext_net_id and new_ext_net_id != org_ext_net_id:
                    # Check whether the gw address has overlapping
                    # with networks attached to the same edge
                    conflict_network_ids = (
                        self._get_conflict_network_ids_by_ext_net(
                            context, router_id))
                    is_migrated = self.edge_manager.is_router_conflict_on_edge(
                        context, router_id, [], conflict_network_ids)
                    if is_migrated:
                        self._remove_router_services_on_edge(context,
                                                             router_id)
                        self._unbind_router_on_edge(context, router_id)

                if not is_migrated:
                    ext_net_ids = self._get_ext_net_ids(context, router_ids)
                    if len(ext_net_ids) > 1:
                        # move all routing service of the router from existing
                        # edge to a new available edge if new_ext_net_id is
                        # changed.
                        self._remove_router_services_on_edge(context,
                                                             router_id)
                        self._unbind_router_on_edge(context, router_id)
                        is_migrated = True
                    else:
                        # Clear gateway info if all routers has no gw conf
                        if (orgnexthop and
                            (org_ext_net_id != new_ext_net_id or
                             len(ext_net_ids) == 0)):
                            LOG.debug("Delete default gateway %s", orgnexthop)
                            edge_utils.clear_gateway(self.nsx_v, context,
                                                     router_id)

                        # Update external vnic if addr or mask is changed
                        if orgaddr != newaddr or orgmask != newmask:
                            self._update_external_interface_on_routers(
                                context, router_id, router_ids)

                        # Update SNAT rules if ext net changed
                        # or ext net not changed but snat is changed.
                        if ((new_ext_net_id != org_ext_net_id) or
                            (new_ext_net_id == org_ext_net_id and
                             new_enable_snat != org_enable_snat)):
                            self._update_nat_rules_on_routers(context,
                                                              router_id,
                                                              router_ids)

                        if (new_ext_net_id != org_ext_net_id or
                            new_enable_snat != org_enable_snat):
                            self._update_subnets_and_dnat_firewall_on_routers(
                                context, router_id, router_ids,
                                allow_external=True)

                        # Update static routes in all.
                        self._update_routes_on_routers(
                            context, router_id, router_ids)
            if is_migrated:
                self._bind_router_on_available_edge(
                    context, router_id, router.admin_state_up)
                edge_id = edge_utils.get_router_edge_id(context, router_id)
                with locking.LockManager.get_lock(
                        str(edge_id),
                        lock_file_prefix=NSXV_ROUTER_RECONFIG,
                        external=True):
                    self._add_router_services_on_available_edge(context,
                                                                router_id)